info: use a session struct in the JSON helpers
authorFerry Huberts <ferry.huberts@pelagic.nl>
Fri, 15 Apr 2016 12:45:14 +0000 (14:45 +0200)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Fri, 15 Apr 2016 15:12:51 +0000 (17:12 +0200)
Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
lib/info/json_helpers.c
lib/info/json_helpers.h
lib/jsoninfo/src/olsrd_jsoninfo.c
lib/netjson/src/olsrd_netjson.c

index 415a31b..4f3b055 100644 (file)
@@ -61,23 +61,18 @@ static const char * empty = "";
 
 /* JSON support functions */
 
-/* JSON does not allow commas dangling at the end of arrays, so we need to
- * count which entry number we're at in order to make sure we don't tack a
- * dangling comma on at the end */
-#define ENTRY_NUMBER_MAX_DEPTH 16
-static int entrynumber[ENTRY_NUMBER_MAX_DEPTH] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-static int currentjsondepth = 0;
-
-void abuf_json_reset_entry_number_and_depth(void) {
-  entrynumber[0] = 0;
-  currentjsondepth = 0;
+void abuf_json_reset_entry_number_and_depth(struct json_session *session) {
+  assert(session);
+
+  memset(session, 0, sizeof(*session));
 }
 
-static void abuf_json_new_indent(struct autobuf *abuf) {
+static void abuf_json_new_indent(struct json_session *session, struct autobuf *abuf) {
+  assert(session);
   assert(abuf);
 
-  if (currentjsondepth) {
-    int i = currentjsondepth;
+  if (session->currentjsondepth) {
+    int i = session->currentjsondepth;
 
     abuf_puts(abuf, "\n");
     while (i-- > 0) {
@@ -86,74 +81,80 @@ static void abuf_json_new_indent(struct autobuf *abuf) {
   }
 }
 
-void abuf_json_insert_comma(struct autobuf *abuf) {
+void abuf_json_insert_comma(struct json_session *session, struct autobuf *abuf) {
+  assert(session);
   assert(abuf);
 
-  if (entrynumber[currentjsondepth])
+  if (session->entrynumber[session->currentjsondepth])
     abuf_appendf(abuf, ",");
 }
 
-void abuf_json_mark_output(bool open, struct autobuf *abuf) {
+void abuf_json_mark_output(struct json_session *session, bool open, struct autobuf *abuf) {
+  assert(session);
   assert(abuf);
 
   if (open) {
-    assert(!currentjsondepth);
-    abuf_json_new_indent(abuf);
+    assert(!session->currentjsondepth);
+    abuf_json_new_indent(session, abuf);
     abuf_puts(abuf, "{");
-    currentjsondepth++;
-    entrynumber[currentjsondepth] = 0;
+    session->currentjsondepth++;
+    session->entrynumber[session->currentjsondepth] = 0;
   } else {
-    assert(currentjsondepth == 1);
-    entrynumber[currentjsondepth] = 0;
-    currentjsondepth--;
-    abuf_json_new_indent(abuf);
+    assert(session->currentjsondepth == 1);
+    session->entrynumber[session->currentjsondepth] = 0;
+    session->currentjsondepth--;
+    abuf_json_new_indent(session, abuf);
     abuf_puts(abuf, "\n}");
   }
 }
 
-void abuf_json_mark_object(bool open, bool array, struct autobuf *abuf, const char* header) {
+void abuf_json_mark_object(struct json_session *session, bool open, bool array, struct autobuf *abuf, const char* header) {
+  assert(session);
   assert(abuf);
 
   if (open) {
-    abuf_json_insert_comma(abuf);
-    abuf_json_new_indent(abuf);
+    abuf_json_insert_comma(session, abuf);
+    abuf_json_new_indent(session, abuf);
     if (header) {
       abuf_appendf(abuf, "\"%s\": %s", header, array ? "[" : "{");
     } else {
       abuf_appendf(abuf, "%s", array ? "[" : "{");
     }
-    entrynumber[currentjsondepth]++;
-    currentjsondepth++;
-    assert(currentjsondepth < ENTRY_NUMBER_MAX_DEPTH);
-    entrynumber[currentjsondepth] = 0;
+    session->entrynumber[session->currentjsondepth]++;
+    session->currentjsondepth++;
+    assert(session->currentjsondepth < INFO_JSON_ENTRY_MAX_DEPTH);
+    session->entrynumber[session->currentjsondepth] = 0;
   } else {
-    entrynumber[currentjsondepth] = 0;
-    currentjsondepth--;
-    assert(currentjsondepth >= 0);
-    abuf_json_new_indent(abuf);
+    session->entrynumber[session->currentjsondepth] = 0;
+    session->currentjsondepth--;
+    assert(session->currentjsondepth >= 0);
+    abuf_json_new_indent(session, abuf);
     abuf_appendf(abuf, "%s", array ? "]" : "}");
   }
 }
 
-void abuf_json_mark_array_entry(bool open, struct autobuf *abuf) {
+void abuf_json_mark_array_entry(struct json_session *session, bool open, struct autobuf *abuf) {
+  assert(session);
   assert(abuf);
 
-  abuf_json_mark_object(open, false, abuf, NULL);
+  abuf_json_mark_object(session, open, false, abuf, NULL);
 }
 
-void abuf_json_boolean(struct autobuf *abuf, const char* key, bool value) {
+void abuf_json_boolean(struct json_session *session, struct autobuf *abuf, const char* key, bool value) {
+  assert(session);
   assert(abuf);
   assert(key);
 
-  abuf_json_insert_comma(abuf);
-  abuf_json_new_indent(abuf);
+  abuf_json_insert_comma(session, abuf);
+  abuf_json_new_indent(session, abuf);
   abuf_appendf(abuf, "\"%s\": %s", key, value ? "true" : "false");
-  entrynumber[currentjsondepth]++;
+  session->entrynumber[session->currentjsondepth]++;
 }
 
-void abuf_json_string(struct autobuf *abuf, const char* key, const char* value) {
+void abuf_json_string(struct json_session *session, struct autobuf *abuf, const char* key, const char* value) {
   const char * val;
 
+  assert(session);
   assert(abuf);
   assert(key || value);
 
@@ -163,19 +164,20 @@ void abuf_json_string(struct autobuf *abuf, const char* key, const char* value)
     val = value;
   }
 
-  abuf_json_insert_comma(abuf);
-  abuf_json_new_indent(abuf);
+  abuf_json_insert_comma(session, abuf);
+  abuf_json_new_indent(session, abuf);
   if (!key) {
     abuf_appendf(abuf, "\"%s\"", value);
   } else {
     abuf_appendf(abuf, "\"%s\": \"%s\"", key, val);
   }
-  entrynumber[currentjsondepth]++;
+  session->entrynumber[session->currentjsondepth]++;
 }
 
-void abuf_json_int(struct autobuf *abuf, const char* key, long long value) {
+void abuf_json_int(struct json_session *session, struct autobuf *abuf, const char* key, long long value) {
   const char * fmt;
 
+  assert(session);
   assert(abuf);
   assert(key);
 
@@ -185,16 +187,17 @@ void abuf_json_int(struct autobuf *abuf, const char* key, long long value) {
   fmt = "\"%s\": %ld";
 #endif
 
-  abuf_json_insert_comma(abuf);
-  abuf_json_new_indent(abuf);
+  abuf_json_insert_comma(session, abuf);
+  abuf_json_new_indent(session, abuf);
   abuf_appendf(abuf, fmt, key, value);
-  entrynumber[currentjsondepth]++;
+  session->entrynumber[session->currentjsondepth]++;
 }
 
-void abuf_json_float(struct autobuf *abuf, const char* key, double value) {
+void abuf_json_float(struct json_session *session, struct autobuf *abuf, const char* key, double value) {
   double v = value;
   int isInf = isinf(v);
 
+  assert(session);
   assert(abuf);
   assert(key);
 
@@ -206,16 +209,17 @@ void abuf_json_float(struct autobuf *abuf, const char* key, double value) {
     v = DBL_MAX;
   }
 
-  abuf_json_insert_comma(abuf);
-  abuf_json_new_indent(abuf);
+  abuf_json_insert_comma(session, abuf);
+  abuf_json_new_indent(session, abuf);
   abuf_appendf(abuf, "\"%s\": %f", key, v);
-  entrynumber[currentjsondepth]++;
+  session->entrynumber[session->currentjsondepth]++;
 }
 
-void abuf_json_ip_address(struct autobuf *abuf, const char* key, union olsr_ip_addr *ip) {
+void abuf_json_ip_address(struct json_session *session, struct autobuf *abuf, const char* key, union olsr_ip_addr *ip) {
   struct ipaddr_str ipStr;
   const char * value;
 
+  assert(session);
   assert(abuf);
   assert(key || ip);
 
@@ -225,20 +229,21 @@ void abuf_json_ip_address(struct autobuf *abuf, const char* key, union olsr_ip_a
     value = olsr_ip_to_string(&ipStr, ip);
   }
 
-  abuf_json_insert_comma(abuf);
-  abuf_json_new_indent(abuf);
+  abuf_json_insert_comma(session, abuf);
+  abuf_json_new_indent(session, abuf);
   if (!key) {
     abuf_appendf(abuf, "\"%s\"", value);
   } else {
     abuf_appendf(abuf, "\"%s\": \"%s\"", key, value);
   }
-  entrynumber[currentjsondepth]++;
+  session->entrynumber[session->currentjsondepth]++;
 }
 
-void abuf_json_ip_address46(struct autobuf *abuf, const char* key, void *ip, int af) {
+void abuf_json_ip_address46(struct json_session *session, struct autobuf *abuf, const char* key, void *ip, int af) {
   struct ipaddr_str ipStr;
   const char * value;
 
+  assert(session);
   assert(abuf);
   assert(key || ip);
 
@@ -250,21 +255,22 @@ void abuf_json_ip_address46(struct autobuf *abuf, const char* key, void *ip, int
     value = ip6_to_string(&ipStr, (const struct in6_addr * const ) ip);
   }
 
-  abuf_json_insert_comma(abuf);
-  abuf_json_new_indent(abuf);
+  abuf_json_insert_comma(session, abuf);
+  abuf_json_new_indent(session, abuf);
   if (!key) {
     abuf_appendf(abuf, "\"%s\"", value);
   } else {
     abuf_appendf(abuf, "\"%s\": \"%s\"", key, value);
   }
-  entrynumber[currentjsondepth]++;
+  session->entrynumber[session->currentjsondepth]++;
 }
 
-void abuf_json_prefix(struct autobuf *abuf, const char* key, struct olsr_ip_prefix *prefix) {
+void abuf_json_prefix(struct json_session *session, struct autobuf *abuf, const char* key, struct olsr_ip_prefix *prefix) {
   struct ipaddr_str ipStr;
   const char * value = empty;
   int prefixLen = INT_MIN;
 
+  assert(session);
   assert(abuf);
   assert(key || prefix);
 
@@ -273,8 +279,8 @@ void abuf_json_prefix(struct autobuf *abuf, const char* key, struct olsr_ip_pref
     prefixLen = prefix->prefix_len;
   }
 
-  abuf_json_insert_comma(abuf);
-  abuf_json_new_indent(abuf);
+  abuf_json_insert_comma(session, abuf);
+  abuf_json_new_indent(session, abuf);
   if (!key) {
     abuf_appendf(abuf, "\"%s", value);
   } else {
@@ -284,5 +290,5 @@ void abuf_json_prefix(struct autobuf *abuf, const char* key, struct olsr_ip_pref
     abuf_appendf(abuf, "/%d", prefixLen);
   }
   abuf_puts(abuf, "\"");
-  entrynumber[currentjsondepth]++;
+  session->entrynumber[session->currentjsondepth]++;
 }
index cf70265..d8b9248 100644 (file)
 
 #include "common/autobuf.h"
 
-void abuf_json_reset_entry_number_and_depth(void);
+#define INFO_JSON_ENTRY_MAX_DEPTH 16
 
-void abuf_json_mark_output(bool open, struct autobuf *abuf);
+/* JSON does not allow commas dangling at the end of arrays, so we need to
+ * count which entry number we're at in order to make sure we don't tack a
+ * dangling comma on at the end
+ */
+struct json_session {
+    int entrynumber[INFO_JSON_ENTRY_MAX_DEPTH];
+    int currentjsondepth;
+};
+
+void abuf_json_reset_entry_number_and_depth(struct json_session *session);
+
+void abuf_json_insert_comma(struct json_session *session, struct autobuf *abuf);
 
-void abuf_json_mark_object(bool open, bool array, struct autobuf *abuf, const char* header);
+void abuf_json_mark_output(struct json_session *session, bool open, struct autobuf *abuf);
 
-void abuf_json_mark_array_entry(bool open, struct autobuf *abuf);
+void abuf_json_mark_object(struct json_session *session, bool open, bool array, struct autobuf *abuf, const char* header);
 
-void abuf_json_insert_comma(struct autobuf *abuf);
+void abuf_json_mark_array_entry(struct json_session *session, bool open, struct autobuf *abuf);
 
-void abuf_json_boolean(struct autobuf *abuf, const char* key, bool value);
+void abuf_json_boolean(struct json_session *session, struct autobuf *abuf, const char* key, bool value);
 
-void abuf_json_string(struct autobuf *abuf, const char* key, const char* value);
+void abuf_json_string(struct json_session *session, struct autobuf *abuf, const char* key, const char* value);
 
-void abuf_json_int(struct autobuf *abuf, const char* key, long long value);
+void abuf_json_int(struct json_session *session, struct autobuf *abuf, const char* key, long long value);
 
-void abuf_json_float(struct autobuf *abuf, const char* key, double value);
+void abuf_json_float(struct json_session *session, struct autobuf *abuf, const char* key, double value);
 
-void abuf_json_ip_address(struct autobuf *abuf, const char* key, union olsr_ip_addr *ip);
+void abuf_json_ip_address(struct json_session *session, struct autobuf *abuf, const char* key, union olsr_ip_addr *ip);
 
-void abuf_json_ip_address46(struct autobuf *abuf, const char* key, void *ip, int af);
+void abuf_json_ip_address46(struct json_session *session, struct autobuf *abuf, const char* key, void *ip, int af);
 
-void abuf_json_prefix(struct autobuf *abuf, const char* key, struct olsr_ip_prefix *prefix);
+void abuf_json_prefix(struct json_session *session, struct autobuf *abuf, const char* key, struct olsr_ip_prefix *prefix);
 
 #endif /* _OLSRD_LIB_INFO_JSON_HELPERS_H_ */
index ed5bbf9..7e9d2b4 100644 (file)
@@ -68,6 +68,8 @@
 #define UUIDLEN 256
 char uuid[UUIDLEN];
 
+static struct json_session json_session;
+
 struct timeval start_time;
 
 static int read_uuid_from_file(const char * name, const char *file) {
@@ -207,19 +209,20 @@ const char * determine_mime_type(unsigned int send_what) {
 
 void output_start(struct autobuf *abuf) {
   /* global variables for tracking when to put a comma in for JSON */
-  abuf_json_reset_entry_number_and_depth();
-  abuf_json_mark_output(true, abuf);
+  abuf_json_reset_entry_number_and_depth(&json_session);
+  abuf_json_mark_output(&json_session, true, abuf);
 
-  abuf_json_int(abuf, "systemTime", time(NULL));
-  abuf_json_int(abuf, "timeSinceStartup", now_times);
+  abuf_json_int(&json_session, abuf, "systemTime", time(NULL));
+  abuf_json_int(&json_session, abuf, "timeSinceStartup", now_times);
   if (*uuid) {
-    abuf_json_string(abuf, "uuid", uuid);
+    abuf_json_string(&json_session, abuf, "uuid", uuid);
   }
 }
 
 void output_end(struct autobuf *abuf) {
-  abuf_json_mark_output(false, abuf);
+  abuf_json_mark_output(&json_session, false, abuf);
   abuf_puts(abuf, "\n");
+  abuf_json_reset_entry_number_and_depth(&json_session);
 }
 
 void output_error(struct autobuf *abuf, unsigned int status, const char * req __attribute__((unused)), bool http_headers) {
@@ -234,154 +237,160 @@ void output_error(struct autobuf *abuf, unsigned int status, const char * req __
   if (status == INFO_HTTP_NOCONTENT) {
     /* do nothing */
   } else {
-    abuf_json_string(abuf, "error", httpStatusToReply(status));
+    abuf_json_string(&json_session, abuf, "error", httpStatusToReply(status));
   }
 
   output_end(abuf);
 }
 
-static void print_msg_params(struct autobuf *abuf, struct olsr_msg_params *params, const char * name) {
+static void print_msg_params(struct json_session *session, struct autobuf *abuf, struct olsr_msg_params *params, const char * name) {
+  assert(session);
   assert(abuf);
   assert(params);
   assert(name);
 
-  abuf_json_mark_object(true, false, abuf, name);
-  abuf_json_float(abuf, "emissionInterval", params->emission_interval);
-  abuf_json_float(abuf, "validityTime", params->validity_time);
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(session, true, false, abuf, name);
+  abuf_json_float(session, abuf, "emissionInterval", params->emission_interval);
+  abuf_json_float(session, abuf, "validityTime", params->validity_time);
+  abuf_json_mark_object(session, false, false, abuf, NULL);
 }
 
-static void print_hna_array_entry(struct autobuf *abuf, union olsr_ip_addr *gw, union olsr_ip_addr *ip, uint8_t prefix_len, long long validityTime) {
+static void print_hna_array_entry(struct json_session *session, struct autobuf *abuf, union olsr_ip_addr *gw, union olsr_ip_addr *ip, uint8_t prefix_len, long long validityTime) {
+  assert(session);
   assert(abuf);
 
-  abuf_json_mark_array_entry(true, abuf);
-  abuf_json_ip_address(abuf, "gateway", gw);
-  abuf_json_ip_address(abuf, "destination", ip);
-  abuf_json_int(abuf, "genmask", prefix_len);
-  abuf_json_int(abuf, "validityTime", validityTime);
-  abuf_json_mark_array_entry(false, abuf);
+  abuf_json_mark_array_entry(session, true, abuf);
+  abuf_json_ip_address(session, abuf, "gateway", gw);
+  abuf_json_ip_address(session, abuf, "destination", ip);
+  abuf_json_int(session, abuf, "genmask", prefix_len);
+  abuf_json_int(session, abuf, "validityTime", validityTime);
+  abuf_json_mark_array_entry(session, false, abuf);
 }
 
-static void print_link_quality_multipliers_array_entry(struct autobuf *abuf, struct olsr_lq_mult *mult) {
+static void print_link_quality_multipliers_array_entry(struct json_session *session, struct autobuf *abuf, struct olsr_lq_mult *mult) {
+  assert(session);
   assert(abuf);
   assert(mult);
 
-  abuf_json_mark_array_entry(true, abuf);
-  abuf_json_ip_address(abuf, "route", &mult->addr);
-  abuf_json_float(abuf, "multiplier", mult->value / 65535.0);
-  abuf_json_mark_array_entry(false, abuf);
+  abuf_json_mark_array_entry(session, true, abuf);
+  abuf_json_ip_address(session, abuf, "route", &mult->addr);
+  abuf_json_float(session, abuf, "multiplier", mult->value / 65535.0);
+  abuf_json_mark_array_entry(session, false, abuf);
 }
 
-static void print_ipc_net_array_entry(struct autobuf *abuf, struct ip_prefix_list *ipc_nets) {
+static void print_ipc_net_array_entry(struct json_session *session, struct autobuf *abuf, struct ip_prefix_list *ipc_nets) {
+  assert(session);
   assert(abuf);
   assert(ipc_nets);
 
-  abuf_json_mark_array_entry(true, abuf);
-  abuf_json_boolean(abuf, "host", (ipc_nets->net.prefix_len == olsr_cnf->maxplen));
-  abuf_json_ip_address(abuf, "ipAddress", &ipc_nets->net.prefix);
-  abuf_json_int(abuf, "genmask", ipc_nets->net.prefix_len);
-  abuf_json_mark_array_entry(false, abuf);
+  abuf_json_mark_array_entry(session, true, abuf);
+  abuf_json_boolean(session, abuf, "host", (ipc_nets->net.prefix_len == olsr_cnf->maxplen));
+  abuf_json_ip_address(session, abuf, "ipAddress", &ipc_nets->net.prefix);
+  abuf_json_int(session, abuf, "genmask", ipc_nets->net.prefix_len);
+  abuf_json_mark_array_entry(session, false, abuf);
 }
 
-static void print_interface_config(struct autobuf *abuf, const char * name, struct if_config_options* id) {
+static void print_interface_config(struct json_session *session, struct autobuf *abuf, const char * name, struct if_config_options* id) {
+  assert(session);
   assert(abuf);
   assert(name);
 
-  abuf_json_mark_object(true, false, abuf, name);
+  abuf_json_mark_object(session, true, false, abuf, name);
   if (id) {
     struct olsr_lq_mult *mult;
 
-    abuf_json_ip_address(abuf, "ipv4Broadcast", &id->ipv4_multicast);
-    abuf_json_ip_address(abuf, "ipv6Multicast", &id->ipv6_multicast);
+    abuf_json_ip_address(session, abuf, "ipv4Broadcast", &id->ipv4_multicast);
+    abuf_json_ip_address(session, abuf, "ipv6Multicast", &id->ipv6_multicast);
 
-    abuf_json_ip_address(abuf, "ipv4Source", &id->ipv4_src);
-    abuf_json_ip_address(abuf, "ipv6Source", &id->ipv6_src.prefix);
-    abuf_json_int(abuf, "ipv6SourcePrefixLength", id->ipv6_src.prefix_len);
+    abuf_json_ip_address(session, abuf, "ipv4Source", &id->ipv4_src);
+    abuf_json_ip_address(session, abuf, "ipv6Source", &id->ipv6_src.prefix);
+    abuf_json_int(session, abuf, "ipv6SourcePrefixLength", id->ipv6_src.prefix_len);
 
-    abuf_json_string(abuf, "mode", ((id->mode < IF_MODE_MESH) || (id->mode >= IF_MODE_CNT)) ? "" : OLSR_IF_MODE[id->mode]);
+    abuf_json_string(session, abuf, "mode", ((id->mode < IF_MODE_MESH) || (id->mode >= IF_MODE_CNT)) ? "" : OLSR_IF_MODE[id->mode]);
 
-    abuf_json_int(abuf, "weightValue", id->weight.value);
-    abuf_json_boolean(abuf, "weightFixed", id->weight.fixed);
-    print_msg_params(abuf, &id->hello_params, "hello");
-    print_msg_params(abuf, &id->tc_params, "tc");
-    print_msg_params(abuf, &id->mid_params, "mid");
-    print_msg_params(abuf, &id->hna_params, "hna");
-    abuf_json_mark_object(true, true, abuf, "linkQualityMultipliers");
+    abuf_json_int(session, abuf, "weightValue", id->weight.value);
+    abuf_json_boolean(session, abuf, "weightFixed", id->weight.fixed);
+    print_msg_params(session, abuf, &id->hello_params, "hello");
+    print_msg_params(session, abuf, &id->tc_params, "tc");
+    print_msg_params(session, abuf, &id->mid_params, "mid");
+    print_msg_params(session, abuf, &id->hna_params, "hna");
+    abuf_json_mark_object(session, true, true, abuf, "linkQualityMultipliers");
     for (mult = olsr_cnf->interface_defaults->lq_mult; mult != NULL ; mult = mult->next) {
-      print_link_quality_multipliers_array_entry(abuf, mult);
+      print_link_quality_multipliers_array_entry(session, abuf, mult);
     }
-    abuf_json_mark_object(false, true, abuf, NULL);
-    abuf_json_int(abuf, "linkQualityMultipliersCount", id->orig_lq_mult_cnt);
-    abuf_json_boolean(abuf, "autoDetectChanges", id->autodetect_chg);
+    abuf_json_mark_object(session, false, true, abuf, NULL);
+    abuf_json_int(session, abuf, "linkQualityMultipliersCount", id->orig_lq_mult_cnt);
+    abuf_json_boolean(session, abuf, "autoDetectChanges", id->autodetect_chg);
   }
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(session, false, false, abuf, NULL);
 }
 
-static void print_interface_olsr(struct autobuf *abuf, const char * name, struct interface_olsr * rifs) {
+static void print_interface_olsr(struct json_session *session, struct autobuf *abuf, const char * name, struct interface_olsr * rifs) {
+  assert(session);
   assert(abuf);
   assert(name);
 
-  abuf_json_mark_object(true, false, abuf, name);
-  abuf_json_boolean(abuf, "up", rifs != NULL);
+  abuf_json_mark_object(session, true, false, abuf, name);
+  abuf_json_boolean(session, abuf, "up", rifs != NULL);
   if (!rifs) {
-    abuf_json_mark_object(false, false, abuf, NULL);
+    abuf_json_mark_object(session, false, false, abuf, NULL);
     return;
   }
 
-  abuf_json_ip_address46(abuf, "ipv4Address", &rifs->int_addr.sin_addr, AF_INET);
-  abuf_json_ip_address46(abuf, "ipv4Netmask", &rifs->int_netmask.sin_addr, AF_INET);
-  abuf_json_ip_address46(abuf, "ipv4Broadcast", &rifs->int_broadaddr.sin_addr, AF_INET);
-  abuf_json_string(abuf, "mode", ((rifs->mode < IF_MODE_MESH) || (rifs->mode >= IF_MODE_CNT)) ? "" : OLSR_IF_MODE[rifs->mode]);
+  abuf_json_ip_address46(session, abuf, "ipv4Address", &rifs->int_addr.sin_addr, AF_INET);
+  abuf_json_ip_address46(session, abuf, "ipv4Netmask", &rifs->int_netmask.sin_addr, AF_INET);
+  abuf_json_ip_address46(session, abuf, "ipv4Broadcast", &rifs->int_broadaddr.sin_addr, AF_INET);
+  abuf_json_string(session, abuf, "mode", ((rifs->mode < IF_MODE_MESH) || (rifs->mode >= IF_MODE_CNT)) ? "" : OLSR_IF_MODE[rifs->mode]);
 
-  abuf_json_ip_address46(abuf, "ipv6Address", &rifs->int6_addr.sin6_addr, AF_INET6);
-  abuf_json_ip_address46(abuf, "ipv6Multicast", &rifs->int6_multaddr.sin6_addr, AF_INET6);
+  abuf_json_ip_address46(session, abuf, "ipv6Address", &rifs->int6_addr.sin6_addr, AF_INET6);
+  abuf_json_ip_address46(session, abuf, "ipv6Multicast", &rifs->int6_multaddr.sin6_addr, AF_INET6);
 
-  abuf_json_ip_address(abuf, "ipAddress", &rifs->ip_addr);
-  abuf_json_boolean(abuf, "emulatedInterface", rifs->is_hcif);
+  abuf_json_ip_address(session, abuf, "ipAddress", &rifs->ip_addr);
+  abuf_json_boolean(session, abuf, "emulatedInterface", rifs->is_hcif);
 
-  abuf_json_int(abuf, "olsrSocket", rifs->olsr_socket);
-  abuf_json_int(abuf, "sendSocket", rifs->send_socket);
+  abuf_json_int(session, abuf, "olsrSocket", rifs->olsr_socket);
+  abuf_json_int(session, abuf, "sendSocket", rifs->send_socket);
 
-  abuf_json_int(abuf, "metric", rifs->int_metric);
-  abuf_json_int(abuf, "mtu", rifs->int_mtu);
-  abuf_json_int(abuf, "flags", rifs->int_flags);
-  abuf_json_int(abuf, "index", rifs->if_index);
-  abuf_json_boolean(abuf, "wireless", rifs->is_wireless);
-  abuf_json_string(abuf, "name", rifs->int_name);
-  abuf_json_int(abuf, "seqNum", rifs->olsr_seqnum);
+  abuf_json_int(session, abuf, "metric", rifs->int_metric);
+  abuf_json_int(session, abuf, "mtu", rifs->int_mtu);
+  abuf_json_int(session, abuf, "flags", rifs->int_flags);
+  abuf_json_int(session, abuf, "index", rifs->if_index);
+  abuf_json_boolean(session, abuf, "wireless", rifs->is_wireless);
+  abuf_json_string(session, abuf, "name", rifs->int_name);
+  abuf_json_int(session, abuf, "seqNum", rifs->olsr_seqnum);
 
 
-  abuf_json_mark_object(true, false, abuf, "messageTimes");
-  abuf_json_int(abuf, "hello", rifs->hello_gen_timer ? (long) (rifs->hello_gen_timer->timer_clock - now_times) : 0);
-  abuf_json_int(abuf, "tc", rifs->tc_gen_timer ? (long) (rifs->tc_gen_timer->timer_clock - now_times) : 0);
-  abuf_json_int(abuf, "mid", rifs->mid_gen_timer ? (long) (rifs->mid_gen_timer->timer_clock - now_times) : 0);
-  abuf_json_int(abuf, "hna", rifs->hna_gen_timer ? (long) (rifs->hna_gen_timer->timer_clock - now_times) : 0);
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(session, true, false, abuf, "messageTimes");
+  abuf_json_int(session, abuf, "hello", rifs->hello_gen_timer ? (long) (rifs->hello_gen_timer->timer_clock - now_times) : 0);
+  abuf_json_int(session, abuf, "tc", rifs->tc_gen_timer ? (long) (rifs->tc_gen_timer->timer_clock - now_times) : 0);
+  abuf_json_int(session, abuf, "mid", rifs->mid_gen_timer ? (long) (rifs->mid_gen_timer->timer_clock - now_times) : 0);
+  abuf_json_int(session, abuf, "hna", rifs->hna_gen_timer ? (long) (rifs->hna_gen_timer->timer_clock - now_times) : 0);
+  abuf_json_mark_object(session, false, false, abuf, NULL);
 
 #ifdef __linux__
 
 
 
 
-  abuf_json_boolean(abuf, "icmpRedirectBackup", rifs->nic_state.redirect);
+  abuf_json_boolean(session, abuf, "icmpRedirectBackup", rifs->nic_state.redirect);
 
 
-  abuf_json_boolean(abuf, "spoofFilterBackup", rifs->nic_state.spoof);
+  abuf_json_boolean(session, abuf, "spoofFilterBackup", rifs->nic_state.spoof);
 
 #endif /* __linux__ */
 
-  abuf_json_int(abuf, "helloEmissionInterval", rifs->hello_etime);
-  abuf_json_mark_object(true, false, abuf, "validityTimes");
-  abuf_json_int(abuf, "hello", me_to_reltime(rifs->valtimes.hello));
-  abuf_json_int(abuf, "tc", me_to_reltime(rifs->valtimes.tc));
-  abuf_json_int(abuf, "mid", me_to_reltime(rifs->valtimes.mid));
-  abuf_json_int(abuf, "hna", me_to_reltime(rifs->valtimes.hna));
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_int(session, abuf, "helloEmissionInterval", rifs->hello_etime);
+  abuf_json_mark_object(session, true, false, abuf, "validityTimes");
+  abuf_json_int(session, abuf, "hello", me_to_reltime(rifs->valtimes.hello));
+  abuf_json_int(session, abuf, "tc", me_to_reltime(rifs->valtimes.tc));
+  abuf_json_int(session, abuf, "mid", me_to_reltime(rifs->valtimes.mid));
+  abuf_json_int(session, abuf, "hna", me_to_reltime(rifs->valtimes.hna));
+  abuf_json_mark_object(session, false, false, abuf, NULL);
 
-  abuf_json_int(abuf, "forwardingTimeout", rifs->fwdtimer);
+  abuf_json_int(session, abuf, "forwardingTimeout", rifs->fwdtimer);
 
 
-  abuf_json_int(abuf, "sgwZeroBwTimeout", rifs->sgw_sgw_zero_bw_timeout);
+  abuf_json_int(session, abuf, "sgwZeroBwTimeout", rifs->sgw_sgw_zero_bw_timeout);
 
 
   // netbuf
@@ -390,16 +399,16 @@ static void print_interface_olsr(struct autobuf *abuf, const char * name, struct
   // gen_properties
 
 
-  abuf_json_int(abuf, "ttlIndex", rifs->ttl_index);
+  abuf_json_int(session, abuf, "ttlIndex", rifs->ttl_index);
 
 
-  abuf_json_boolean(abuf, "immediateSendTc", rifs->immediate_send_tc);
+  abuf_json_boolean(session, abuf, "immediateSendTc", rifs->immediate_send_tc);
 
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(session, false, false, abuf, NULL);
 }
 
 #ifdef __linux__
-static void ipc_print_gateway_entry(struct autobuf *abuf, bool ipv6, struct gateway_entry * current_gw, struct gateway_entry * gw) {
+static void ipc_print_gateway_entry(struct json_session *session, struct autobuf *abuf, bool ipv6, struct gateway_entry * current_gw, struct gateway_entry * gw) {
   struct tc_entry* tc;
 
   assert(abuf);
@@ -407,34 +416,34 @@ static void ipc_print_gateway_entry(struct autobuf *abuf, bool ipv6, struct gate
 
   tc = olsr_lookup_tc_entry(&gw->originator);
 
-  abuf_json_boolean(abuf, "selected", current_gw && (current_gw == gw));
-  abuf_json_boolean(abuf, "selectable", isGwSelectable(gw, ipv6));
-  abuf_json_ip_address(abuf, "originator", &gw->originator);
-  abuf_json_ip_address(abuf, "prefix", &gw->external_prefix.prefix);
-  abuf_json_int(abuf, "prefixLen", gw->external_prefix.prefix_len);
-  abuf_json_int(abuf, "uplink", gw->uplink);
-  abuf_json_int(abuf, "downlink", gw->downlink);
-  abuf_json_float(abuf, "cost", get_gwcost_scaled(gw->path_cost));
-  abuf_json_boolean(abuf, "IPv4", gw->ipv4);
-  abuf_json_boolean(abuf, "IPv4-NAT", gw->ipv4nat);
-  abuf_json_boolean(abuf, "IPv6", gw->ipv6);
-  abuf_json_int(abuf, "expireTime", gw->expire_timer ? (gw->expire_timer->timer_clock - now_times) : 0);
-  abuf_json_int(abuf, "cleanupTime", gw->cleanup_timer ? (gw->cleanup_timer->timer_clock - now_times) : 0);
-
-  abuf_json_float(abuf, "pathcost", get_linkcost_scaled(!tc ? ROUTE_COST_BROKEN : tc->path_cost, true));
-  abuf_json_int(abuf, "hops", !tc ? 0 : tc->hops);
+  abuf_json_boolean(session, abuf, "selected", current_gw && (current_gw == gw));
+  abuf_json_boolean(session, abuf, "selectable", isGwSelectable(gw, ipv6));
+  abuf_json_ip_address(session, abuf, "originator", &gw->originator);
+  abuf_json_ip_address(session, abuf, "prefix", &gw->external_prefix.prefix);
+  abuf_json_int(session, abuf, "prefixLen", gw->external_prefix.prefix_len);
+  abuf_json_int(session, abuf, "uplink", gw->uplink);
+  abuf_json_int(session, abuf, "downlink", gw->downlink);
+  abuf_json_float(session, abuf, "cost", get_gwcost_scaled(gw->path_cost));
+  abuf_json_boolean(session, abuf, "IPv4", gw->ipv4);
+  abuf_json_boolean(session, abuf, "IPv4-NAT", gw->ipv4nat);
+  abuf_json_boolean(session, abuf, "IPv6", gw->ipv6);
+  abuf_json_int(session, abuf, "expireTime", gw->expire_timer ? (gw->expire_timer->timer_clock - now_times) : 0);
+  abuf_json_int(session, abuf, "cleanupTime", gw->cleanup_timer ? (gw->cleanup_timer->timer_clock - now_times) : 0);
+
+  abuf_json_float(session, abuf, "pathcost", get_linkcost_scaled(!tc ? ROUTE_COST_BROKEN : tc->path_cost, true));
+  abuf_json_int(session, abuf, "hops", !tc ? 0 : tc->hops);
 }
 #endif /* __linux__ */
 
-static void ipc_print_neighbors_internal(struct autobuf *abuf, bool list_2hop) {
+static void ipc_print_neighbors_internal(struct json_session *session, struct autobuf *abuf, bool list_2hop) {
   struct neighbor_entry *neigh;
 
   assert(abuf);
 
   if (!list_2hop) {
-    abuf_json_mark_object(true, true, abuf, "neighbors");
+    abuf_json_mark_object(session, true, true, abuf, "neighbors");
   } else {
-    abuf_json_mark_object(true, true, abuf, "2hop");
+    abuf_json_mark_object(session, true, true, abuf, "2hop");
   }
 
   /* Neighbors */
@@ -442,48 +451,48 @@ static void ipc_print_neighbors_internal(struct autobuf *abuf, bool list_2hop) {
     struct neighbor_2_list_entry *list_2;
     int thop_cnt = 0;
 
-    abuf_json_mark_array_entry(true, abuf);
+    abuf_json_mark_array_entry(session, true, abuf);
 
-    abuf_json_ip_address(abuf, "ipAddress", &neigh->neighbor_main_addr);
-    abuf_json_boolean(abuf, "symmetric", (neigh->status == SYM));
-    abuf_json_int(abuf, "willingness", neigh->willingness);
-    abuf_json_boolean(abuf, "isMultiPointRelay", neigh->is_mpr);
-    abuf_json_boolean(abuf, "wasMultiPointRelay", neigh->was_mpr);
-    abuf_json_boolean(abuf, "multiPointRelaySelector", olsr_lookup_mprs_set(&neigh->neighbor_main_addr) != NULL);
-    abuf_json_boolean(abuf, "skip", neigh->skip);
-    abuf_json_int(abuf, "neighbor2nocov", neigh->neighbor_2_nocov);
-    abuf_json_int(abuf, "linkcount", neigh->linkcount);
+    abuf_json_ip_address(session, abuf, "ipAddress", &neigh->neighbor_main_addr);
+    abuf_json_boolean(session, abuf, "symmetric", (neigh->status == SYM));
+    abuf_json_int(session, abuf, "willingness", neigh->willingness);
+    abuf_json_boolean(session, abuf, "isMultiPointRelay", neigh->is_mpr);
+    abuf_json_boolean(session, abuf, "wasMultiPointRelay", neigh->was_mpr);
+    abuf_json_boolean(session, abuf, "multiPointRelaySelector", olsr_lookup_mprs_set(&neigh->neighbor_main_addr) != NULL);
+    abuf_json_boolean(session, abuf, "skip", neigh->skip);
+    abuf_json_int(session, abuf, "neighbor2nocov", neigh->neighbor_2_nocov);
+    abuf_json_int(session, abuf, "linkcount", neigh->linkcount);
 
     if (list_2hop) {
-      abuf_json_mark_object(true, true, abuf, "twoHopNeighbors");
+      abuf_json_mark_object(session, true, true, abuf, "twoHopNeighbors");
     }
 
     thop_cnt = 0;
     for (list_2 = neigh->neighbor_2_list.next; list_2 != &neigh->neighbor_2_list; list_2 = list_2->next) {
       if (list_2hop && list_2->neighbor_2) {
-        abuf_json_ip_address(abuf, NULL, &list_2->neighbor_2->neighbor_2_addr);
+        abuf_json_ip_address(session, abuf, NULL, &list_2->neighbor_2->neighbor_2_addr);
       }
       thop_cnt++;
     }
 
     if (list_2hop) {
-      abuf_json_mark_object(false, true, abuf, NULL);
+      abuf_json_mark_object(session, false, true, abuf, NULL);
     }
-    abuf_json_int(abuf, "twoHopNeighborCount", thop_cnt);
+    abuf_json_int(session, abuf, "twoHopNeighborCount", thop_cnt);
 
-    abuf_json_mark_array_entry(false, abuf);
+    abuf_json_mark_array_entry(session, false, abuf);
   } OLSR_FOR_ALL_NBR_ENTRIES_END(neigh);
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(session, false, true, abuf, NULL);
 }
 
 void ipc_print_neighbors(struct autobuf *abuf) {
-  ipc_print_neighbors_internal(abuf, false);
+  ipc_print_neighbors_internal(&json_session, abuf, false);
 }
 
 void ipc_print_links(struct autobuf *abuf) {
   struct link_entry *my_link;
 
-  abuf_json_mark_object(true, true, abuf, "links");
+  abuf_json_mark_object(&json_session, true, true, abuf, "links");
 
   OLSR_FOR_ALL_LINK_ENTRIES(my_link) {
     struct lqtextbuffer lqBuffer;
@@ -495,70 +504,70 @@ void ipc_print_links(struct autobuf *abuf) {
       nlqString++;
     }
 
-    abuf_json_mark_array_entry(true, abuf);
+    abuf_json_mark_array_entry(&json_session, true, abuf);
 
-    abuf_json_ip_address(abuf, "localIP", &my_link->local_iface_addr);
-    abuf_json_ip_address(abuf, "remoteIP", &my_link->neighbor_iface_addr);
-    abuf_json_string(abuf, "olsrInterface", (my_link->inter && my_link->inter->int_name) ? my_link->inter->int_name : "");
-    abuf_json_string(abuf, "ifName", my_link->if_name ? my_link->if_name : "");
-    abuf_json_int(abuf, "validityTime", my_link->link_timer ? (long) (my_link->link_timer->timer_clock - now_times) : 0);
-    abuf_json_int(abuf, "symmetryTime", my_link->link_sym_timer ? (long) (my_link->link_sym_timer->timer_clock - now_times) : 0);
-    abuf_json_int(abuf, "asymmetryTime", my_link->ASYM_time);
-    abuf_json_int(abuf, "vtime", (long) my_link->vtime);
+    abuf_json_ip_address(&json_session, abuf, "localIP", &my_link->local_iface_addr);
+    abuf_json_ip_address(&json_session, abuf, "remoteIP", &my_link->neighbor_iface_addr);
+    abuf_json_string(&json_session, abuf, "olsrInterface", (my_link->inter && my_link->inter->int_name) ? my_link->inter->int_name : "");
+    abuf_json_string(&json_session, abuf, "ifName", my_link->if_name ? my_link->if_name : "");
+    abuf_json_int(&json_session, abuf, "validityTime", my_link->link_timer ? (long) (my_link->link_timer->timer_clock - now_times) : 0);
+    abuf_json_int(&json_session, abuf, "symmetryTime", my_link->link_sym_timer ? (long) (my_link->link_sym_timer->timer_clock - now_times) : 0);
+    abuf_json_int(&json_session, abuf, "asymmetryTime", my_link->ASYM_time);
+    abuf_json_int(&json_session, abuf, "vtime", (long) my_link->vtime);
     // neighbor (no need to print, can be looked up via neighbours)
-    abuf_json_string(abuf, "currentLinkStatus", linkTypeToString(lookup_link_status(my_link)));
-    abuf_json_string(abuf, "previousLinkStatus", linkTypeToString(my_link->prev_status));
+    abuf_json_string(&json_session, abuf, "currentLinkStatus", linkTypeToString(lookup_link_status(my_link)));
+    abuf_json_string(&json_session, abuf, "previousLinkStatus", linkTypeToString(my_link->prev_status));
 
-    abuf_json_float(abuf, "hysteresis", my_link->L_link_quality);
-    abuf_json_boolean(abuf, "pending", my_link->L_link_pending != 0);
-    abuf_json_int(abuf, "lostLinkTime", (long) my_link->L_LOST_LINK_time);
-    abuf_json_int(abuf, "helloTime", my_link->link_hello_timer ? (long) (my_link->link_hello_timer->timer_clock - now_times) : 0);
-    abuf_json_int(abuf, "lastHelloTime", (long) my_link->last_htime);
-    abuf_json_boolean(abuf, "seqnoValid", my_link->olsr_seqno_valid);
-    abuf_json_int(abuf, "seqno", my_link->olsr_seqno);
+    abuf_json_float(&json_session, abuf, "hysteresis", my_link->L_link_quality);
+    abuf_json_boolean(&json_session, abuf, "pending", my_link->L_link_pending != 0);
+    abuf_json_int(&json_session, abuf, "lostLinkTime", (long) my_link->L_LOST_LINK_time);
+    abuf_json_int(&json_session, abuf, "helloTime", my_link->link_hello_timer ? (long) (my_link->link_hello_timer->timer_clock - now_times) : 0);
+    abuf_json_int(&json_session, abuf, "lastHelloTime", (long) my_link->last_htime);
+    abuf_json_boolean(&json_session, abuf, "seqnoValid", my_link->olsr_seqno_valid);
+    abuf_json_int(&json_session, abuf, "seqno", my_link->olsr_seqno);
 
-    abuf_json_int(abuf, "lossHelloInterval", (long) my_link->loss_helloint);
-    abuf_json_int(abuf, "lossTime", my_link->link_loss_timer ? (long) (my_link->link_loss_timer->timer_clock - now_times) : 0);
+    abuf_json_int(&json_session, abuf, "lossHelloInterval", (long) my_link->loss_helloint);
+    abuf_json_int(&json_session, abuf, "lossTime", my_link->link_loss_timer ? (long) (my_link->link_loss_timer->timer_clock - now_times) : 0);
 
-    abuf_json_int(abuf, "lossMultiplier", (long) my_link->loss_link_multiplier);
+    abuf_json_int(&json_session, abuf, "lossMultiplier", (long) my_link->loss_link_multiplier);
 
-    abuf_json_float(abuf, "linkCost", get_linkcost_scaled(my_link->linkcost, false));
+    abuf_json_float(&json_session, abuf, "linkCost", get_linkcost_scaled(my_link->linkcost, false));
 
-    abuf_json_float(abuf, "linkQuality", atof(lqString));
-    abuf_json_float(abuf, "neighborLinkQuality", nlqString ? atof(nlqString) : 0.0);
+    abuf_json_float(&json_session, abuf, "linkQuality", atof(lqString));
+    abuf_json_float(&json_session, abuf, "neighborLinkQuality", nlqString ? atof(nlqString) : 0.0);
 
-    abuf_json_mark_array_entry(false, abuf);
+    abuf_json_mark_array_entry(&json_session, false, abuf);
   } OLSR_FOR_ALL_LINK_ENTRIES_END(my_link);
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL);
 }
 
 void ipc_print_routes(struct autobuf *abuf) {
   struct rt_entry *rt;
 
-  abuf_json_mark_object(true, true, abuf, "routes");
+  abuf_json_mark_object(&json_session, true, true, abuf, "routes");
 
   /* Walk the route table */
   OLSR_FOR_ALL_RT_ENTRIES(rt) {
     if (rt->rt_best) {
-      abuf_json_mark_array_entry(true, abuf);
-      abuf_json_ip_address(abuf, "destination", &rt->rt_dst.prefix);
-      abuf_json_int(abuf, "genmask", rt->rt_dst.prefix_len);
-      abuf_json_ip_address(abuf, "gateway", &rt->rt_best->rtp_nexthop.gateway);
-      abuf_json_int(abuf, "metric", rt->rt_best->rtp_metric.hops);
-      abuf_json_float(abuf, "etx", get_linkcost_scaled(rt->rt_best->rtp_metric.cost, true));
-      abuf_json_float(abuf, "rtpMetricCost", get_linkcost_scaled(rt->rt_best->rtp_metric.cost, true));
-      abuf_json_string(abuf, "networkInterface", if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
-      abuf_json_mark_array_entry(false, abuf);
+      abuf_json_mark_array_entry(&json_session, true, abuf);
+      abuf_json_ip_address(&json_session, abuf, "destination", &rt->rt_dst.prefix);
+      abuf_json_int(&json_session, abuf, "genmask", rt->rt_dst.prefix_len);
+      abuf_json_ip_address(&json_session, abuf, "gateway", &rt->rt_best->rtp_nexthop.gateway);
+      abuf_json_int(&json_session, abuf, "metric", rt->rt_best->rtp_metric.hops);
+      abuf_json_float(&json_session, abuf, "etx", get_linkcost_scaled(rt->rt_best->rtp_metric.cost, true));
+      abuf_json_float(&json_session, abuf, "rtpMetricCost", get_linkcost_scaled(rt->rt_best->rtp_metric.cost, true));
+      abuf_json_string(&json_session, abuf, "networkInterface", if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
+      abuf_json_mark_array_entry(&json_session, false, abuf);
     }
   } OLSR_FOR_ALL_RT_ENTRIES_END(rt);
 
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL);
 }
 
 void ipc_print_topology(struct autobuf *abuf) {
   struct tc_entry *tc;
 
-  abuf_json_mark_object(true, true, abuf, "topology");
+  abuf_json_mark_object(&json_session, true, true, abuf, "topology");
 
   /* Topology */
   OLSR_FOR_ALL_TC_ENTRIES(tc) {
@@ -574,53 +583,54 @@ void ipc_print_topology(struct autobuf *abuf) {
           nlqString++;
         }
 
-        abuf_json_mark_array_entry(true, abuf);
+        abuf_json_mark_array_entry(&json_session, true, abuf);
 
         // vertex_node
-        abuf_json_ip_address(abuf, "lastHopIP", &tc->addr);
+        abuf_json_ip_address(&json_session, abuf, "lastHopIP", &tc->addr);
         // cand_tree_node
-        abuf_json_float(abuf, "pathCost", get_linkcost_scaled(tc->path_cost, true));
+        abuf_json_float(&json_session, abuf, "pathCost", get_linkcost_scaled(tc->path_cost, true));
         // path_list_node
         // edge_tree
         // prefix_tree
         // next_hop
         // edge_gc_timer
-        abuf_json_int(abuf, "validityTime", tc->validity_timer ? (tc->validity_timer->timer_clock - now_times) : 0);
-        abuf_json_int(abuf, "refCount", tc->refcount);
-        abuf_json_int(abuf, "msgSeq", tc->msg_seq);
-        abuf_json_int(abuf, "msgHops", tc->msg_hops);
-        abuf_json_int(abuf, "hops", tc->hops);
-        abuf_json_int(abuf, "ansn", tc->ansn);
-        abuf_json_int(abuf, "tcIgnored", tc->ignored);
+        abuf_json_int(&json_session, abuf, "validityTime", tc->validity_timer ? (tc->validity_timer->timer_clock - now_times) : 0);
+        abuf_json_int(&json_session, abuf, "refCount", tc->refcount);
+        abuf_json_int(&json_session, abuf, "msgSeq", tc->msg_seq);
+        abuf_json_int(&json_session, abuf, "msgHops", tc->msg_hops);
+        abuf_json_int(&json_session, abuf, "hops", tc->hops);
+        abuf_json_int(&json_session, abuf, "ansn", tc->ansn);
+        abuf_json_int(&json_session, abuf, "tcIgnored", tc->ignored);
 
-        abuf_json_int(abuf, "errSeq", tc->err_seq);
-        abuf_json_boolean(abuf, "errSeqValid", tc->err_seq_valid);
+        abuf_json_int(&json_session, abuf, "errSeq", tc->err_seq);
+        abuf_json_boolean(&json_session, abuf, "errSeqValid", tc->err_seq_valid);
 
         // edge_node
-        abuf_json_ip_address(abuf, "destinationIP", &tc_edge->T_dest_addr);
+        abuf_json_ip_address(&json_session, abuf, "destinationIP", &tc_edge->T_dest_addr);
         // tc
-        abuf_json_float(abuf, "tcEdgeCost", get_linkcost_scaled(tc_edge->cost, true));
-        abuf_json_int(abuf, "ansnEdge", tc_edge->ansn);
-        abuf_json_float(abuf, "linkQuality", atof(lqString));
-        abuf_json_float(abuf, "neighborLinkQuality", nlqString ? atof(nlqString) : 0.0);
+        abuf_json_float(&json_session, abuf, "tcEdgeCost", get_linkcost_scaled(tc_edge->cost, true));
+        abuf_json_int(&json_session, abuf, "ansnEdge", tc_edge->ansn);
+        abuf_json_float(&json_session, abuf, "linkQuality", atof(lqString));
+        abuf_json_float(&json_session, abuf, "neighborLinkQuality", nlqString ? atof(nlqString) : 0.0);
 
-        abuf_json_mark_array_entry(false, abuf);
+        abuf_json_mark_array_entry(&json_session, false, abuf);
       }
     } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);
   } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
 
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL);
 }
 
 void ipc_print_hna(struct autobuf *abuf) {
   struct ip_prefix_list *hna;
   struct hna_entry *tmp_hna;
 
-  abuf_json_mark_object(true, true, abuf, "hna");
+  abuf_json_mark_object(&json_session, true, true, abuf, "hna");
 
   /* Announced HNA entries */
   for (hna = olsr_cnf->hna_entries; hna != NULL ; hna = hna->next) {
     print_hna_array_entry( //
+        &json_session, //
         abuf, //
         &olsr_cnf->main_addr, //
         &hna->net.prefix, //
@@ -634,6 +644,7 @@ void ipc_print_hna(struct autobuf *abuf) {
     /* Check all networks */
     for (tmp_net = tmp_hna->networks.next; tmp_net != &tmp_hna->networks; tmp_net = tmp_net->next) {
       print_hna_array_entry( //
+          &json_session, //
           abuf, //
           &tmp_hna->A_gateway_addr, //
           &tmp_net->hna_prefix.prefix, //
@@ -642,54 +653,54 @@ void ipc_print_hna(struct autobuf *abuf) {
     }
   } OLSR_FOR_ALL_HNA_ENTRIES_END(tmp_hna);
 
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL);
 }
 
 void ipc_print_mid(struct autobuf *abuf) {
   int idx;
 
-  abuf_json_mark_object(true, true, abuf, "mid");
+  abuf_json_mark_object(&json_session, true, true, abuf, "mid");
 
   /* MID */
   for (idx = 0; idx < HASHSIZE; idx++) {
     struct mid_entry * entry = mid_set[idx].next;
 
     while (entry != &mid_set[idx]) {
-      abuf_json_mark_array_entry(true, abuf);
+      abuf_json_mark_array_entry(&json_session, true, abuf);
 
-      abuf_json_mark_object(true, false, abuf, "main");
-      abuf_json_ip_address(abuf, "ipAddress", &entry->main_addr);
-      abuf_json_int(abuf, "validityTime", entry->mid_timer ? (entry->mid_timer->timer_clock - now_times) : 0);
-      abuf_json_mark_object(false, false, abuf, NULL); // main
+      abuf_json_mark_object(&json_session, true, false, abuf, "main");
+      abuf_json_ip_address(&json_session, abuf, "ipAddress", &entry->main_addr);
+      abuf_json_int(&json_session, abuf, "validityTime", entry->mid_timer ? (entry->mid_timer->timer_clock - now_times) : 0);
+      abuf_json_mark_object(&json_session, false, false, abuf, NULL); // main
 
       {
         struct mid_address * alias = entry->aliases;
 
-        abuf_json_mark_object(true, true, abuf, "aliases");
+        abuf_json_mark_object(&json_session, true, true, abuf, "aliases");
         while (alias) {
-          abuf_json_mark_array_entry(true, abuf);
-          abuf_json_ip_address(abuf, "ipAddress", &alias->alias);
-          abuf_json_int(abuf, "validityTime", alias->vtime - now_times);
-          abuf_json_mark_array_entry(false, abuf);
+          abuf_json_mark_array_entry(&json_session, true, abuf);
+          abuf_json_ip_address(&json_session, abuf, "ipAddress", &alias->alias);
+          abuf_json_int(&json_session, abuf, "validityTime", alias->vtime - now_times);
+          abuf_json_mark_array_entry(&json_session, false, abuf);
 
           alias = alias->next_alias;
         }
-        abuf_json_mark_object(false, true, abuf, NULL); // aliases
+        abuf_json_mark_object(&json_session, false, true, abuf, NULL); // aliases
       }
-      abuf_json_mark_array_entry(false, abuf); // entry
+      abuf_json_mark_array_entry(&json_session, false, abuf); // entry
 
       entry = entry->next;
     }
   }
-  abuf_json_mark_object(false, true, abuf, NULL); // mid
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL); // mid
 }
 
 #ifdef __linux__
 
-static void ipc_print_gateways_ipvx(struct autobuf *abuf, bool ipv6) {
+static void ipc_print_gateways_ipvx(struct json_session *session, struct autobuf *abuf, bool ipv6) {
   assert(abuf);
 
-  abuf_json_mark_object(true, true, abuf, ipv6 ? "ipv6" : "ipv4");
+  abuf_json_mark_object(session, true, true, abuf, ipv6 ? "ipv6" : "ipv4");
 
   if (olsr_cnf->smart_gw_active) {
     struct gateway_entry * current_gw = olsr_get_inet_gateway(ipv6);
@@ -700,26 +711,26 @@ static void ipc_print_gateways_ipvx(struct autobuf *abuf, bool ipv6) {
         continue;
       }
 
-      abuf_json_mark_array_entry(true, abuf);
-      ipc_print_gateway_entry(abuf, ipv6, current_gw, gw);
-      abuf_json_mark_array_entry(false, abuf);
+      abuf_json_mark_array_entry(session, true, abuf);
+      ipc_print_gateway_entry(session, abuf, ipv6, current_gw, gw);
+      abuf_json_mark_array_entry(session, false, abuf);
     } OLSR_FOR_ALL_GATEWAY_ENTRIES_END(gw)
   }
 
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(session, false, true, abuf, NULL);
 }
 #endif /* __linux__ */
 
 void ipc_print_gateways(struct autobuf *abuf) {
 #ifndef __linux__
-  abuf_json_string(abuf, "error", "Gateway mode is only supported in Linux");
+  abuf_json_string(&json_session, abuf, "error", "Gateway mode is only supported in Linux");
 #else /* __linux__ */
-  abuf_json_mark_object(true, false, abuf, "gateways");
+  abuf_json_mark_object(&json_session, true, false, abuf, "gateways");
 
-  ipc_print_gateways_ipvx(abuf, false);
-  ipc_print_gateways_ipvx(abuf, true);
+  ipc_print_gateways_ipvx(&json_session, abuf, false);
+  ipc_print_gateways_ipvx(&json_session, abuf, true);
 
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 #endif /* __linux__ */
 }
 
@@ -738,14 +749,14 @@ extern struct interfaceName * sgwTunnel6InterfaceNames;
  * @param ipv6 true for IPv6, false for IPv4
  * @param fmtv the format for printing
  */
-static void sgw_ipvx(struct autobuf *abuf, bool ipv6) {
+static void sgw_ipvx(struct json_session *session, struct autobuf *abuf, bool ipv6) {
   struct interfaceName * sgwTunnelInterfaceNames;
 
   assert(abuf);
 
   sgwTunnelInterfaceNames = !ipv6 ? sgwTunnel4InterfaceNames : sgwTunnel6InterfaceNames;
 
-  abuf_json_mark_object(true, true, abuf, ipv6 ? "ipv6" : "ipv4");
+  abuf_json_mark_object(session, true, true, abuf, ipv6 ? "ipv6" : "ipv4");
 
   if (olsr_cnf->smart_gw_active && sgwTunnelInterfaceNames) {
     struct gateway_entry * current_gw = olsr_get_inet_gateway(ipv6);
@@ -758,123 +769,123 @@ static void sgw_ipvx(struct autobuf *abuf, bool ipv6) {
         continue;
       }
 
-      abuf_json_mark_array_entry(true, abuf);
-      ipc_print_gateway_entry(abuf, ipv6, current_gw, gw);
-      abuf_json_ip_address(abuf, "destination", &gw->originator);
-      abuf_json_string(abuf, "tunnel", node->name);
-      abuf_json_int(abuf, "tableNr", node->tableNr);
-      abuf_json_int(abuf, "ruleNr", node->ruleNr);
-      abuf_json_int(abuf, "bypassRuleNr", node->bypassRuleNr);
-      abuf_json_mark_array_entry(false, abuf);
+      abuf_json_mark_array_entry(session, true, abuf);
+      ipc_print_gateway_entry(session, abuf, ipv6, current_gw, gw);
+      abuf_json_ip_address(session, abuf, "destination", &gw->originator);
+      abuf_json_string(session, abuf, "tunnel", node->name);
+      abuf_json_int(session, abuf, "tableNr", node->tableNr);
+      abuf_json_int(session, abuf, "ruleNr", node->ruleNr);
+      abuf_json_int(session, abuf, "bypassRuleNr", node->bypassRuleNr);
+      abuf_json_mark_array_entry(session, false, abuf);
     }
   }
 
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(session, false, true, abuf, NULL);
 }
 
-static void sgw_egress_bw(struct autobuf * abuf, const char * key, struct egress_if_bw * bw) {
-  abuf_json_mark_object(true, false, abuf, key);
+static void sgw_egress_bw(struct json_session *session, struct autobuf * abuf, const char * key, struct egress_if_bw * bw) {
+  abuf_json_mark_object(session, true, false, abuf, key);
 
-  abuf_json_int(abuf, "egressUk", bw->egressUk);
-  abuf_json_int(abuf, "egressDk", bw->egressDk);
-  abuf_json_float(abuf, "pathCost", get_linkcost_scaled(bw->path_cost, true));
-  abuf_json_ip_address(abuf, "network", &bw->network.prefix);
-  abuf_json_int(abuf, "networkLength", bw->network.prefix_len);
-  abuf_json_ip_address(abuf, "gateway", &bw->gateway);
-  abuf_json_boolean(abuf, "networkSet", bw->networkSet);
-  abuf_json_boolean(abuf, "gatewaySet", bw->gatewaySet);
-  abuf_json_float(abuf, "costs", get_gwcost_scaled(bw->costs));
+  abuf_json_int(session, abuf, "egressUk", bw->egressUk);
+  abuf_json_int(session, abuf, "egressDk", bw->egressDk);
+  abuf_json_float(session, abuf, "pathCost", get_linkcost_scaled(bw->path_cost, true));
+  abuf_json_ip_address(session, abuf, "network", &bw->network.prefix);
+  abuf_json_int(session, abuf, "networkLength", bw->network.prefix_len);
+  abuf_json_ip_address(session, abuf, "gateway", &bw->gateway);
+  abuf_json_boolean(session, abuf, "networkSet", bw->networkSet);
+  abuf_json_boolean(session, abuf, "gatewaySet", bw->gatewaySet);
+  abuf_json_float(session, abuf, "costs", get_gwcost_scaled(bw->costs));
 
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(session, false, false, abuf, NULL);
 }
 
-static void sgw_egress_route_info(struct autobuf * abuf, const char * key, struct sgw_route_info * ri) {
-  abuf_json_mark_object(true, false, abuf, key);
-
-  abuf_json_boolean(abuf, "active", ri->active);
-  abuf_json_int(abuf, "family", ri->route.family);
-  abuf_json_int(abuf, "rtTable", ri->route.rttable);
-  abuf_json_int(abuf, "flags", ri->route.flags);
-  abuf_json_int(abuf, "scope", ri->route.scope);
-  abuf_json_int(abuf, "ifIndex", ri->route.if_index);
-  abuf_json_int(abuf, "metric", ri->route.metric);
-  abuf_json_int(abuf, "protocol", ri->route.protocol);
-  abuf_json_boolean(abuf, "srcSet", ri->route.srcSet);
-  abuf_json_boolean(abuf, "gwSet", ri->route.gwSet);
-  abuf_json_boolean(abuf, "dstSet", ri->route.dstSet);
-  abuf_json_boolean(abuf, "delSimilar", ri->route.del_similar);
-  abuf_json_boolean(abuf, "blackhole", ri->route.blackhole);
-  abuf_json_ip_address(abuf, "srcStore", &ri->route.srcStore);
-  abuf_json_ip_address(abuf, "gwStore", &ri->route.gwStore);
-  abuf_json_ip_address(abuf, "dstStore", &ri->route.dstStore.prefix);
-  abuf_json_int(abuf, "dstStoreLength", ri->route.dstStore.prefix_len);
-
-  abuf_json_mark_object(false, false, abuf, NULL);
+static void sgw_egress_route_info(struct json_session *session, struct autobuf * abuf, const char * key, struct sgw_route_info * ri) {
+  abuf_json_mark_object(session, true, false, abuf, key);
+
+  abuf_json_boolean(session, abuf, "active", ri->active);
+  abuf_json_int(session, abuf, "family", ri->route.family);
+  abuf_json_int(session, abuf, "rtTable", ri->route.rttable);
+  abuf_json_int(session, abuf, "flags", ri->route.flags);
+  abuf_json_int(session, abuf, "scope", ri->route.scope);
+  abuf_json_int(session, abuf, "ifIndex", ri->route.if_index);
+  abuf_json_int(session, abuf, "metric", ri->route.metric);
+  abuf_json_int(session, abuf, "protocol", ri->route.protocol);
+  abuf_json_boolean(session, abuf, "srcSet", ri->route.srcSet);
+  abuf_json_boolean(session, abuf, "gwSet", ri->route.gwSet);
+  abuf_json_boolean(session, abuf, "dstSet", ri->route.dstSet);
+  abuf_json_boolean(session, abuf, "delSimilar", ri->route.del_similar);
+  abuf_json_boolean(session, abuf, "blackhole", ri->route.blackhole);
+  abuf_json_ip_address(session, abuf, "srcStore", &ri->route.srcStore);
+  abuf_json_ip_address(session, abuf, "gwStore", &ri->route.gwStore);
+  abuf_json_ip_address(session, abuf, "dstStore", &ri->route.dstStore.prefix);
+  abuf_json_int(session, abuf, "dstStoreLength", ri->route.dstStore.prefix_len);
+
+  abuf_json_mark_object(session, false, false, abuf, NULL);
 }
 
-static void sgw_egress(struct autobuf * abuf) {
+static void sgw_egress(struct json_session *session, struct autobuf * abuf) {
   struct sgw_egress_if * egress_if;
 
-  abuf_json_mark_object(true, true, abuf, "egress");
+  abuf_json_mark_object(session, true, true, abuf, "egress");
 
   egress_if = olsr_cnf->smart_gw_egress_interfaces;
   while (egress_if) {
-    abuf_json_mark_array_entry(true, abuf);
-
-    abuf_json_boolean(abuf, "selected", isEgressSelected(egress_if));
-    abuf_json_string(abuf, "name", egress_if->name);
-    abuf_json_int(abuf, "ifIndex", egress_if->if_index);
-    abuf_json_int(abuf, "tableNr", egress_if->tableNr);
-    abuf_json_int(abuf, "ruleNr", egress_if->ruleNr);
-    abuf_json_int(abuf, "bypassRuleNr", egress_if->bypassRuleNr);
-    abuf_json_boolean(abuf, "upPrevious", egress_if->upPrevious);
-    abuf_json_boolean(abuf, "upCurrent", egress_if->upCurrent);
-    abuf_json_boolean(abuf, "upChanged", egress_if->upChanged);
-    sgw_egress_bw(abuf, "bwPrevious", &egress_if->bwPrevious);
-    sgw_egress_bw(abuf, "bwCurrent", &egress_if->bwCurrent);
-    abuf_json_boolean(abuf, "bwCostsChanged", egress_if->bwCostsChanged);
-    abuf_json_boolean(abuf, "bwNetworkChanged", egress_if->bwNetworkChanged);
-    abuf_json_boolean(abuf, "bwGatewayChanged", egress_if->bwGatewayChanged);
-    abuf_json_boolean(abuf, "bwChanged", egress_if->bwChanged);
-    sgw_egress_route_info(abuf, "networkRouteCurrent", &egress_if->networkRouteCurrent);
-    sgw_egress_route_info(abuf, "egressRouteCurrent", &egress_if->egressRouteCurrent);
-    abuf_json_boolean(abuf, "inEgressFile", egress_if->inEgressFile);
-
-    abuf_json_mark_array_entry(false, abuf);
+    abuf_json_mark_array_entry(session, true, abuf);
+
+    abuf_json_boolean(session, abuf, "selected", isEgressSelected(egress_if));
+    abuf_json_string(session, abuf, "name", egress_if->name);
+    abuf_json_int(session, abuf, "ifIndex", egress_if->if_index);
+    abuf_json_int(session, abuf, "tableNr", egress_if->tableNr);
+    abuf_json_int(session, abuf, "ruleNr", egress_if->ruleNr);
+    abuf_json_int(session, abuf, "bypassRuleNr", egress_if->bypassRuleNr);
+    abuf_json_boolean(session, abuf, "upPrevious", egress_if->upPrevious);
+    abuf_json_boolean(session, abuf, "upCurrent", egress_if->upCurrent);
+    abuf_json_boolean(session, abuf, "upChanged", egress_if->upChanged);
+    sgw_egress_bw(session, abuf, "bwPrevious", &egress_if->bwPrevious);
+    sgw_egress_bw(session, abuf, "bwCurrent", &egress_if->bwCurrent);
+    abuf_json_boolean(session, abuf, "bwCostsChanged", egress_if->bwCostsChanged);
+    abuf_json_boolean(session, abuf, "bwNetworkChanged", egress_if->bwNetworkChanged);
+    abuf_json_boolean(session, abuf, "bwGatewayChanged", egress_if->bwGatewayChanged);
+    abuf_json_boolean(session, abuf, "bwChanged", egress_if->bwChanged);
+    sgw_egress_route_info(session, abuf, "networkRouteCurrent", &egress_if->networkRouteCurrent);
+    sgw_egress_route_info(session, abuf, "egressRouteCurrent", &egress_if->egressRouteCurrent);
+    abuf_json_boolean(session, abuf, "inEgressFile", egress_if->inEgressFile);
+
+    abuf_json_mark_array_entry(session, false, abuf);
     egress_if = egress_if->next;
   }
 
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(session, false, true, abuf, NULL);
 }
 #endif /* __linux__ */
 
 void ipc_print_sgw(struct autobuf *abuf) {
 #ifndef __linux__
-  abuf_json_string(abuf, "error", "Gateway mode is only supported in Linux");
+  abuf_json_string(&json_session, abuf, "error", "Gateway mode is only supported in Linux");
 #else
-  abuf_json_mark_object(true, false, abuf, "sgw");
+  abuf_json_mark_object(&json_session, true, false, abuf, "sgw");
 
-  sgw_egress(abuf);
-  sgw_ipvx(abuf, false);
-  sgw_ipvx(abuf, true);
+  sgw_egress(&json_session, abuf);
+  sgw_ipvx(&json_session, abuf, false);
+  sgw_ipvx(&json_session, abuf, true);
 
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 #endif /* __linux__ */
 }
 
 void ipc_print_version(struct autobuf *abuf) {
-  abuf_json_mark_object(true, false, abuf, "version");
+  abuf_json_mark_object(&json_session, true, false, abuf, "version");
 
-  abuf_json_string(abuf, "version", olsrd_version);
+  abuf_json_string(&json_session, abuf, "version", olsrd_version);
 
-  abuf_json_string(abuf, "date", build_date);
-  abuf_json_string(abuf, "host", build_host);
-  abuf_json_string(abuf, "gitDescriptor", git_descriptor);
-  abuf_json_string(abuf, "gitSha", git_sha);
-  abuf_json_string(abuf, "releaseVersion", release_version);
-  abuf_json_string(abuf, "sourceHash", source_hash);
+  abuf_json_string(&json_session, abuf, "date", build_date);
+  abuf_json_string(&json_session, abuf, "host", build_host);
+  abuf_json_string(&json_session, abuf, "gitDescriptor", git_descriptor);
+  abuf_json_string(&json_session, abuf, "gitSha", git_sha);
+  abuf_json_string(&json_session, abuf, "releaseVersion", release_version);
+  abuf_json_string(&json_session, abuf, "sourceHash", source_hash);
 
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 }
 
 void ipc_print_olsrd_conf(struct autobuf *abuf) {
@@ -884,216 +895,217 @@ void ipc_print_olsrd_conf(struct autobuf *abuf) {
 void ipc_print_interfaces(struct autobuf *abuf) {
   struct olsr_if *ifs;
 
-  abuf_json_mark_object(true, true, abuf, "interfaces");
+  abuf_json_mark_object(&json_session, true, true, abuf, "interfaces");
   for (ifs = olsr_cnf->interfaces; ifs != NULL ; ifs = ifs->next) {
-    abuf_json_mark_array_entry(true, abuf);
-    abuf_json_string(abuf, "name", ifs->name);
-    abuf_json_boolean(abuf, "configured", ifs->configured);
-    abuf_json_boolean(abuf, "hostEmulation", ifs->host_emul);
-    abuf_json_ip_address(abuf, "hostEmulationAddress", &ifs->hemu_ip);
-    print_interface_olsr(abuf, "olsrInterface", ifs->interf);
-    print_interface_config(abuf, "InterfaceConfiguration", ifs->cnf);
-    print_interface_config(abuf, "InterfaceConfigurationDefaults", ifs->cnfi);
-    abuf_json_mark_array_entry(false, abuf);
+    abuf_json_mark_array_entry(&json_session, true, abuf);
+    abuf_json_string(&json_session, abuf, "name", ifs->name);
+    abuf_json_boolean(&json_session, abuf, "configured", ifs->configured);
+    abuf_json_boolean(&json_session, abuf, "hostEmulation", ifs->host_emul);
+    abuf_json_ip_address(&json_session, abuf, "hostEmulationAddress", &ifs->hemu_ip);
+    print_interface_olsr(&json_session, abuf, "olsrInterface", ifs->interf);
+    print_interface_config(&json_session, abuf, "InterfaceConfiguration", ifs->cnf);
+    print_interface_config(&json_session, abuf, "InterfaceConfigurationDefaults", ifs->cnfi);
+    abuf_json_mark_array_entry(&json_session, false, abuf);
   }
-  abuf_json_mark_object(false, true, abuf, NULL); // interfaces
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL); // interfaces
 }
 
 void ipc_print_twohop(struct autobuf *abuf) {
-  ipc_print_neighbors_internal(abuf, true);
+  ipc_print_neighbors_internal(&json_session, abuf, true);
 }
 
 void ipc_print_config(struct autobuf *abuf) {
-  abuf_json_mark_object(true, false, abuf, "config");
-
-  abuf_json_string(abuf, "configurationFile", olsr_cnf->configuration_file);
-  abuf_json_int(abuf, "olsrPort", olsr_cnf->olsrport);
-  abuf_json_int(abuf, "debugLevel", olsr_cnf->debug_level);
-  abuf_json_boolean(abuf, "noFork", olsr_cnf->no_fork);
-  abuf_json_string(abuf, "pidFile", olsr_cnf->pidfile);
-  abuf_json_boolean(abuf, "hostEmulation", olsr_cnf->host_emul);
-  abuf_json_int(abuf, "ipVersion", (olsr_cnf->ip_version == AF_INET) ? 4 : 6);
-  abuf_json_boolean(abuf, "allowNoInt", olsr_cnf->allow_no_interfaces);
-  abuf_json_int(abuf, "tosValue", olsr_cnf->tos);
-
-  abuf_json_int(abuf, "rtProto", olsr_cnf->rt_proto);
-  abuf_json_mark_object(true, false, abuf, "rtTable");
-  abuf_json_int(abuf, "main", olsr_cnf->rt_table);
-  abuf_json_int(abuf, "default", olsr_cnf->rt_table_default);
-  abuf_json_int(abuf, "tunnel", olsr_cnf->rt_table_tunnel);
-  abuf_json_int(abuf, "priority", olsr_cnf->rt_table_pri);
-  abuf_json_int(abuf, "tunnelPriority", olsr_cnf->rt_table_tunnel_pri);
-  abuf_json_int(abuf, "defaultOlsrPriority", olsr_cnf->rt_table_defaultolsr_pri);
-  abuf_json_int(abuf, "defaultPriority", olsr_cnf->rt_table_default_pri);
-  abuf_json_mark_object(false, false, abuf, NULL);
-
-  abuf_json_mark_object(true, false, abuf, "willingness");
-  abuf_json_int(abuf, "willingness", olsr_cnf->willingness);
-  abuf_json_boolean(abuf, "auto", olsr_cnf->willingness_auto);
-  abuf_json_float(abuf, "updateInterval", olsr_cnf->will_int);
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, true, false, abuf, "config");
+
+  abuf_json_string(&json_session, abuf, "configurationFile", olsr_cnf->configuration_file);
+  abuf_json_int(&json_session, abuf, "olsrPort", olsr_cnf->olsrport);
+  abuf_json_int(&json_session, abuf, "debugLevel", olsr_cnf->debug_level);
+  abuf_json_boolean(&json_session, abuf, "noFork", olsr_cnf->no_fork);
+  abuf_json_string(&json_session, abuf, "pidFile", olsr_cnf->pidfile);
+  abuf_json_boolean(&json_session, abuf, "hostEmulation", olsr_cnf->host_emul);
+  abuf_json_int(&json_session, abuf, "ipVersion", (olsr_cnf->ip_version == AF_INET) ? 4 : 6);
+  abuf_json_boolean(&json_session, abuf, "allowNoInt", olsr_cnf->allow_no_interfaces);
+  abuf_json_int(&json_session, abuf, "tosValue", olsr_cnf->tos);
+
+  abuf_json_int(&json_session, abuf, "rtProto", olsr_cnf->rt_proto);
+  abuf_json_mark_object(&json_session, true, false, abuf, "rtTable");
+  abuf_json_int(&json_session, abuf, "main", olsr_cnf->rt_table);
+  abuf_json_int(&json_session, abuf, "default", olsr_cnf->rt_table_default);
+  abuf_json_int(&json_session, abuf, "tunnel", olsr_cnf->rt_table_tunnel);
+  abuf_json_int(&json_session, abuf, "priority", olsr_cnf->rt_table_pri);
+  abuf_json_int(&json_session, abuf, "tunnelPriority", olsr_cnf->rt_table_tunnel_pri);
+  abuf_json_int(&json_session, abuf, "defaultOlsrPriority", olsr_cnf->rt_table_defaultolsr_pri);
+  abuf_json_int(&json_session, abuf, "defaultPriority", olsr_cnf->rt_table_default_pri);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
+
+  abuf_json_mark_object(&json_session, true, false, abuf, "willingness");
+  abuf_json_int(&json_session, abuf, "willingness", olsr_cnf->willingness);
+  abuf_json_boolean(&json_session, abuf, "auto", olsr_cnf->willingness_auto);
+  abuf_json_float(&json_session, abuf, "updateInterval", olsr_cnf->will_int);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 
 
   // ipc_connections: later
 
-  abuf_json_mark_object(true, false, abuf, "fib");
-  abuf_json_string(abuf, "metric", ((olsr_cnf->fib_metric < FIBM_FLAT) || (olsr_cnf->fib_metric >= FIBM_CNT)) ? "" : FIB_METRIC_TXT[olsr_cnf->fib_metric]);
-  abuf_json_string(abuf, "metricDefault", FIB_METRIC_TXT[olsr_cnf->fib_metric_default]);
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, true, false, abuf, "fib");
+  abuf_json_string(&json_session, abuf, "metric", ((olsr_cnf->fib_metric < FIBM_FLAT) || (olsr_cnf->fib_metric >= FIBM_CNT)) ? "" : FIB_METRIC_TXT[olsr_cnf->fib_metric]);
+  abuf_json_string(&json_session, abuf, "metricDefault", FIB_METRIC_TXT[olsr_cnf->fib_metric_default]);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 
 
-  abuf_json_mark_object(true, false, abuf, "hysteresis");
-  abuf_json_boolean(abuf, "enabled", olsr_cnf->use_hysteresis);
-  abuf_json_float(abuf, "scaling", olsr_cnf->hysteresis_param.scaling);
-  abuf_json_float(abuf, "thresholdLow", olsr_cnf->hysteresis_param.thr_low);
-  abuf_json_float(abuf, "thresholdHigh", olsr_cnf->hysteresis_param.thr_high);
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, true, false, abuf, "hysteresis");
+  abuf_json_boolean(&json_session, abuf, "enabled", olsr_cnf->use_hysteresis);
+  abuf_json_float(&json_session, abuf, "scaling", olsr_cnf->hysteresis_param.scaling);
+  abuf_json_float(&json_session, abuf, "thresholdLow", olsr_cnf->hysteresis_param.thr_low);
+  abuf_json_float(&json_session, abuf, "thresholdHigh", olsr_cnf->hysteresis_param.thr_high);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 
   // plugins: later
   // hna_entries
   {
     struct ip_prefix_list *hna;
 
-    abuf_json_mark_object(true, true, abuf, "hna");
+    abuf_json_mark_object(&json_session, true, true, abuf, "hna");
 
     /* Announced HNA entries */
     for (hna = olsr_cnf->hna_entries; hna; hna = hna->next) {
         print_hna_array_entry( //
+            &json_session, //
             abuf, //
             &olsr_cnf->main_addr, //
             &hna->net.prefix, //
             hna->net.prefix_len, //
             0);
     }
-    abuf_json_mark_object(false, true, abuf, NULL);
+    abuf_json_mark_object(&json_session, false, true, abuf, NULL);
   }
   // ipc_nets: later
   // interface_defaults: later
   // interfaces: later
-  abuf_json_float(abuf, "pollrate", olsr_cnf->pollrate);
-  abuf_json_float(abuf, "nicChgsPollInt", olsr_cnf->nic_chgs_pollrate);
-  abuf_json_boolean(abuf, "clearScreen", olsr_cnf->clear_screen);
-  abuf_json_int(abuf, "tcRedundancy", olsr_cnf->tc_redundancy);
-  abuf_json_int(abuf, "mprCoverage", olsr_cnf->mpr_coverage);
-
-
-  abuf_json_mark_object(true, false, abuf, "linkQuality");
-  abuf_json_int(abuf, "level", olsr_cnf->lq_level);
-  abuf_json_boolean(abuf, "fishEye", olsr_cnf->lq_fish);
-  abuf_json_float(abuf, "aging", olsr_cnf->lq_aging);
-  abuf_json_string(abuf, "algorithm", olsr_cnf->lq_algorithm);
-  abuf_json_mark_object(false, false, abuf, NULL);
-
-  abuf_json_float(abuf, "minTCVTime", olsr_cnf->min_tc_vtime);
-
-  abuf_json_boolean(abuf, "setIpForward", olsr_cnf->set_ip_forward);
-
-  abuf_json_string(abuf, "lockFile", olsr_cnf->lock_file);
-  abuf_json_boolean(abuf, "useNiit", olsr_cnf->use_niit);
-
-  abuf_json_mark_object(true, false, abuf, "smartGateway");
-  abuf_json_boolean(abuf, "enabled", olsr_cnf->smart_gw_active);
-  abuf_json_boolean(abuf, "alwaysRemoveServerTunnel", olsr_cnf->smart_gw_always_remove_server_tunnel);
-  abuf_json_boolean(abuf, "allowNAT", olsr_cnf->smart_gw_allow_nat);
-  abuf_json_boolean(abuf, "uplinkNAT", olsr_cnf->smart_gw_uplink_nat);
-  abuf_json_int(abuf, "useCount", olsr_cnf->smart_gw_use_count);
-  abuf_json_int(abuf, "takeDownPercentage", olsr_cnf->smart_gw_takedown_percentage);
-  abuf_json_string(abuf, "instanceId", olsr_cnf->smart_gw_instance_id);
-  abuf_json_string(abuf, "policyRoutingScript", olsr_cnf->smart_gw_policyrouting_script);
-
-  abuf_json_mark_object(true, false, abuf, "egress");
+  abuf_json_float(&json_session, abuf, "pollrate", olsr_cnf->pollrate);
+  abuf_json_float(&json_session, abuf, "nicChgsPollInt", olsr_cnf->nic_chgs_pollrate);
+  abuf_json_boolean(&json_session, abuf, "clearScreen", olsr_cnf->clear_screen);
+  abuf_json_int(&json_session, abuf, "tcRedundancy", olsr_cnf->tc_redundancy);
+  abuf_json_int(&json_session, abuf, "mprCoverage", olsr_cnf->mpr_coverage);
+
+
+  abuf_json_mark_object(&json_session, true, false, abuf, "linkQuality");
+  abuf_json_int(&json_session, abuf, "level", olsr_cnf->lq_level);
+  abuf_json_boolean(&json_session, abuf, "fishEye", olsr_cnf->lq_fish);
+  abuf_json_float(&json_session, abuf, "aging", olsr_cnf->lq_aging);
+  abuf_json_string(&json_session, abuf, "algorithm", olsr_cnf->lq_algorithm);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
+
+  abuf_json_float(&json_session, abuf, "minTCVTime", olsr_cnf->min_tc_vtime);
+
+  abuf_json_boolean(&json_session, abuf, "setIpForward", olsr_cnf->set_ip_forward);
+
+  abuf_json_string(&json_session, abuf, "lockFile", olsr_cnf->lock_file);
+  abuf_json_boolean(&json_session, abuf, "useNiit", olsr_cnf->use_niit);
+
+  abuf_json_mark_object(&json_session, true, false, abuf, "smartGateway");
+  abuf_json_boolean(&json_session, abuf, "enabled", olsr_cnf->smart_gw_active);
+  abuf_json_boolean(&json_session, abuf, "alwaysRemoveServerTunnel", olsr_cnf->smart_gw_always_remove_server_tunnel);
+  abuf_json_boolean(&json_session, abuf, "allowNAT", olsr_cnf->smart_gw_allow_nat);
+  abuf_json_boolean(&json_session, abuf, "uplinkNAT", olsr_cnf->smart_gw_uplink_nat);
+  abuf_json_int(&json_session, abuf, "useCount", olsr_cnf->smart_gw_use_count);
+  abuf_json_int(&json_session, abuf, "takeDownPercentage", olsr_cnf->smart_gw_takedown_percentage);
+  abuf_json_string(&json_session, abuf, "instanceId", olsr_cnf->smart_gw_instance_id);
+  abuf_json_string(&json_session, abuf, "policyRoutingScript", olsr_cnf->smart_gw_policyrouting_script);
+
+  abuf_json_mark_object(&json_session, true, false, abuf, "egress");
   // smart_gw_egress_interfaces
   {
     struct sgw_egress_if * egressif = olsr_cnf->smart_gw_egress_interfaces;
 
-    abuf_json_mark_object(true, true, abuf, "interfaces");
+    abuf_json_mark_object(&json_session, true, true, abuf, "interfaces");
     while (egressif) {
-      abuf_json_string(abuf, NULL, egressif->name);
+      abuf_json_string(&json_session, abuf, NULL, egressif->name);
       egressif = egressif->next;
     }
-    abuf_json_mark_object(false, true, abuf, NULL);
+    abuf_json_mark_object(&json_session, false, true, abuf, NULL);
   }
-  abuf_json_int(abuf, "interfacesCount", olsr_cnf->smart_gw_egress_interfaces_count);
-  abuf_json_string(abuf, "file", olsr_cnf->smart_gw_egress_file);
-  abuf_json_int(abuf, "filePeriod", olsr_cnf->smart_gw_egress_file_period);
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_int(&json_session, abuf, "interfacesCount", olsr_cnf->smart_gw_egress_interfaces_count);
+  abuf_json_string(&json_session, abuf, "file", olsr_cnf->smart_gw_egress_file);
+  abuf_json_int(&json_session, abuf, "filePeriod", olsr_cnf->smart_gw_egress_file_period);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 
-  abuf_json_string(abuf, "statusFile", olsr_cnf->smart_gw_status_file);
-  abuf_json_int(abuf, "tablesOffset", olsr_cnf->smart_gw_offset_tables);
-  abuf_json_int(abuf, "rulesOffset", olsr_cnf->smart_gw_offset_rules);
-  abuf_json_int(abuf, "period", olsr_cnf->smart_gw_period);
-  abuf_json_int(abuf, "stableCount", olsr_cnf->smart_gw_stablecount);
-  abuf_json_int(abuf, "threshold", olsr_cnf->smart_gw_thresh);
+  abuf_json_string(&json_session, abuf, "statusFile", olsr_cnf->smart_gw_status_file);
+  abuf_json_int(&json_session, abuf, "tablesOffset", olsr_cnf->smart_gw_offset_tables);
+  abuf_json_int(&json_session, abuf, "rulesOffset", olsr_cnf->smart_gw_offset_rules);
+  abuf_json_int(&json_session, abuf, "period", olsr_cnf->smart_gw_period);
+  abuf_json_int(&json_session, abuf, "stableCount", olsr_cnf->smart_gw_stablecount);
+  abuf_json_int(&json_session, abuf, "threshold", olsr_cnf->smart_gw_thresh);
 
-  abuf_json_mark_object(true, false, abuf, "costsCalculation");
-  abuf_json_int(abuf, "exitLinkUp", olsr_cnf->smart_gw_weight_exitlink_up);
-  abuf_json_int(abuf, "exitLinkDown", olsr_cnf->smart_gw_weight_exitlink_down);
-  abuf_json_int(abuf, "etx", olsr_cnf->smart_gw_weight_etx);
-  abuf_json_int(abuf, "dividerEtx", olsr_cnf->smart_gw_divider_etx);
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, true, false, abuf, "costsCalculation");
+  abuf_json_int(&json_session, abuf, "exitLinkUp", olsr_cnf->smart_gw_weight_exitlink_up);
+  abuf_json_int(&json_session, abuf, "exitLinkDown", olsr_cnf->smart_gw_weight_exitlink_down);
+  abuf_json_int(&json_session, abuf, "etx", olsr_cnf->smart_gw_weight_etx);
+  abuf_json_int(&json_session, abuf, "dividerEtx", olsr_cnf->smart_gw_divider_etx);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 
-  abuf_json_int(abuf, "maxCostMaxEtx", olsr_cnf->smart_gw_path_max_cost_etx_max);
-  abuf_json_string(abuf, "uplink", ((olsr_cnf->smart_gw_type < GW_UPLINK_NONE) || (olsr_cnf->smart_gw_type >= GW_UPLINK_CNT)) ? "" : GW_UPLINK_TXT[olsr_cnf->smart_gw_type]);
+  abuf_json_int(&json_session, abuf, "maxCostMaxEtx", olsr_cnf->smart_gw_path_max_cost_etx_max);
+  abuf_json_string(&json_session, abuf, "uplink", ((olsr_cnf->smart_gw_type < GW_UPLINK_NONE) || (olsr_cnf->smart_gw_type >= GW_UPLINK_CNT)) ? "" : GW_UPLINK_TXT[olsr_cnf->smart_gw_type]);
 
-  abuf_json_mark_object(true, false, abuf, "bandwidth");
-  abuf_json_int(abuf, "uplinkKbps", olsr_cnf->smart_gw_uplink);
-  abuf_json_int(abuf, "downlinkKbps", olsr_cnf->smart_gw_downlink);
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, true, false, abuf, "bandwidth");
+  abuf_json_int(&json_session, abuf, "uplinkKbps", olsr_cnf->smart_gw_uplink);
+  abuf_json_int(&json_session, abuf, "downlinkKbps", olsr_cnf->smart_gw_downlink);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 
-  abuf_json_mark_object(true, false, abuf, "prefix");
-  abuf_json_ip_address(abuf, "prefix", &olsr_cnf->smart_gw_prefix.prefix);
-  abuf_json_int(abuf, "length", olsr_cnf->smart_gw_prefix.prefix_len);
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, true, false, abuf, "prefix");
+  abuf_json_ip_address(&json_session, abuf, "prefix", &olsr_cnf->smart_gw_prefix.prefix);
+  abuf_json_int(&json_session, abuf, "length", olsr_cnf->smart_gw_prefix.prefix_len);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 
 
-  abuf_json_ip_address(abuf, "mainIp", &olsr_cnf->main_addr);
-  abuf_json_ip_address(abuf, "unicastSourceIpAddress", &olsr_cnf->unicast_src_ip);
-  abuf_json_boolean(abuf, "srcIpRoutes", olsr_cnf->use_src_ip_routes);
+  abuf_json_ip_address(&json_session, abuf, "mainIp", &olsr_cnf->main_addr);
+  abuf_json_ip_address(&json_session, abuf, "unicastSourceIpAddress", &olsr_cnf->unicast_src_ip);
+  abuf_json_boolean(&json_session, abuf, "srcIpRoutes", olsr_cnf->use_src_ip_routes);
 
 
-  abuf_json_int(abuf, "maxPrefixLength", olsr_cnf->maxplen);
-  abuf_json_int(abuf, "ipSize", olsr_cnf->ipsize);
-  abuf_json_boolean(abuf, "delgw", olsr_cnf->del_gws);
-  abuf_json_float(abuf, "maxSendMessageJitter", olsr_cnf->max_jitter);
-  abuf_json_int(abuf, "exitValue", olsr_cnf->exit_value);
-  abuf_json_float(abuf, "maxTcValidTime", olsr_cnf->max_tc_vtime);
+  abuf_json_int(&json_session, abuf, "maxPrefixLength", olsr_cnf->maxplen);
+  abuf_json_int(&json_session, abuf, "ipSize", olsr_cnf->ipsize);
+  abuf_json_boolean(&json_session, abuf, "delgw", olsr_cnf->del_gws);
+  abuf_json_float(&json_session, abuf, "maxSendMessageJitter", olsr_cnf->max_jitter);
+  abuf_json_int(&json_session, abuf, "exitValue", olsr_cnf->exit_value);
+  abuf_json_float(&json_session, abuf, "maxTcValidTime", olsr_cnf->max_tc_vtime);
 
-  abuf_json_int(abuf, "niit4to6InterfaceIndex", olsr_cnf->niit4to6_if_index);
-  abuf_json_int(abuf, "niit6to4InterfaceIndex", olsr_cnf->niit6to4_if_index);
+  abuf_json_int(&json_session, abuf, "niit4to6InterfaceIndex", olsr_cnf->niit4to6_if_index);
+  abuf_json_int(&json_session, abuf, "niit6to4InterfaceIndex", olsr_cnf->niit6to4_if_index);
 
 
-  abuf_json_boolean(abuf, "hasIpv4Gateway", olsr_cnf->has_ipv4_gateway);
-  abuf_json_boolean(abuf, "hasIpv6Gateway", olsr_cnf->has_ipv6_gateway);
+  abuf_json_boolean(&json_session, abuf, "hasIpv4Gateway", olsr_cnf->has_ipv4_gateway);
+  abuf_json_boolean(&json_session, abuf, "hasIpv6Gateway", olsr_cnf->has_ipv6_gateway);
 
-  abuf_json_int(abuf, "ioctlSocket", olsr_cnf->ioctl_s);
+  abuf_json_int(&json_session, abuf, "ioctlSocket", olsr_cnf->ioctl_s);
 #ifdef __linux__
-  abuf_json_int(abuf, "routeNetlinkSocket", olsr_cnf->rtnl_s);
-  abuf_json_int(abuf, "routeMonitorSocket", olsr_cnf->rt_monitor_socket);
+  abuf_json_int(&json_session, abuf, "routeNetlinkSocket", olsr_cnf->rtnl_s);
+  abuf_json_int(&json_session, abuf, "routeMonitorSocket", olsr_cnf->rt_monitor_socket);
 #endif /* __linux__ */
 
 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
-  abuf_json_int(abuf, "routeChangeSocket", olsr_cnf->rts);
+  abuf_json_int(&json_session, abuf, "routeChangeSocket", olsr_cnf->rts);
 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
-  abuf_json_float(abuf, "linkQualityNatThreshold", olsr_cnf->lq_nat_thresh);
+  abuf_json_float(&json_session, abuf, "linkQualityNatThreshold", olsr_cnf->lq_nat_thresh);
 
 
   // Other settings
-  abuf_json_int(abuf, "brokenLinkCost", LINK_COST_BROKEN);
-  abuf_json_int(abuf, "brokenRouteCost", ROUTE_COST_BROKEN);
+  abuf_json_int(&json_session, abuf, "brokenLinkCost", LINK_COST_BROKEN);
+  abuf_json_int(&json_session, abuf, "brokenRouteCost", ROUTE_COST_BROKEN);
 
 
   // IpcConnect section
-  abuf_json_int(abuf, "ipcConnectMaxConnections", olsr_cnf->ipc_connections);
+  abuf_json_int(&json_session, abuf, "ipcConnectMaxConnections", olsr_cnf->ipc_connections);
   {
     struct ip_prefix_list *ipc_nets;
 
-    abuf_json_mark_object(true, true, abuf, "ipcConnectAllowed");
+    abuf_json_mark_object(&json_session, true, true, abuf, "ipcConnectAllowed");
     for (ipc_nets = olsr_cnf->ipc_nets; ipc_nets; ipc_nets = ipc_nets->next) {
-      print_ipc_net_array_entry(abuf, ipc_nets);
+      print_ipc_net_array_entry(&json_session, abuf, ipc_nets);
     }
-    abuf_json_mark_object(false, true, abuf, NULL);
+    abuf_json_mark_object(&json_session, false, true, abuf, NULL);
   }
 
 
@@ -1101,7 +1113,7 @@ void ipc_print_config(struct autobuf *abuf) {
 
 
   // InterfaceDefaults section
-  print_interface_config(abuf, "interfaceDefaults", olsr_cnf->interface_defaults);
+  print_interface_config(&json_session, abuf, "interfaceDefaults", olsr_cnf->interface_defaults);
 
 
   // Interface(s) section: use /interfaces
@@ -1109,47 +1121,47 @@ void ipc_print_config(struct autobuf *abuf) {
 
   // OS section
 #if defined _WIN32 || defined _WIN64
-  abuf_json_string(abuf, "os", "Windows");
+  abuf_json_string(&json_session, abuf, "os", "Windows");
 #elif defined __gnu_linux__
-  abuf_json_string(abuf, "os", "GNU/Linux");
+  abuf_json_string(&json_session, abuf, "os", "GNU/Linux");
 #elif defined __ANDROID__
-  abuf_json_string(abuf, "os", "Android");
+  abuf_json_string(&json_session, abuf, "os", "Android");
 #elif defined __APPLE__
-  abuf_json_string(abuf, "os", "Mac OS X");
+  abuf_json_string(&json_session, abuf, "os", "Mac OS X");
 #elif defined __NetBSD__
-  abuf_json_string(abuf, "os", "NetBSD");
+  abuf_json_string(&json_session, abuf, "os", "NetBSD");
 #elif defined __OpenBSD__
-  abuf_json_string(abuf, "os", "OpenBSD");
+  abuf_json_string(&json_session, abuf, "os", "OpenBSD");
 #elif defined __FreeBSD__ || defined __FreeBSD_kernel__
-  abuf_json_string(abuf, "os", "FreeBSD");
+  abuf_json_string(&json_session, abuf, "os", "FreeBSD");
 #else /* OS detection */
-  abuf_json_string(abuf, "os", "Undefined");
+  abuf_json_string(&json_session, abuf, "os", "Undefined");
 #endif /* OS detection */
 
-  abuf_json_int(abuf, "startTime", start_time.tv_sec);
+  abuf_json_int(&json_session, abuf, "startTime", start_time.tv_sec);
 
-  abuf_json_mark_object(false, false, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 }
 
 void ipc_print_plugins(struct autobuf *abuf) {
-  abuf_json_mark_object(true, true, abuf, "plugins");
+  abuf_json_mark_object(&json_session, true, true, abuf, "plugins");
   if (olsr_cnf->plugins) {
     struct plugin_entry *plugin;
 
     for (plugin = olsr_cnf->plugins; plugin; plugin = plugin->next) {
       struct plugin_param *param;
 
-      abuf_json_mark_array_entry(true, abuf);
-      abuf_json_string(abuf, "plugin", plugin->name);
+      abuf_json_mark_array_entry(&json_session, true, abuf);
+      abuf_json_string(&json_session, abuf, "plugin", plugin->name);
 
-      abuf_json_mark_object(true, false, abuf, "parameters");
+      abuf_json_mark_object(&json_session, true, false, abuf, "parameters");
       for (param = plugin->params; param; param = param->next) {
-        abuf_json_string(abuf, param->key, param->value);
+        abuf_json_string(&json_session, abuf, param->key, param->value);
       }
-      abuf_json_mark_object(false, false, abuf, NULL);
+      abuf_json_mark_object(&json_session, false, false, abuf, NULL);
 
-      abuf_json_mark_array_entry(false, abuf);
+      abuf_json_mark_array_entry(&json_session, false, abuf);
     }
   }
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL);
 }
index d441258..3c15e3c 100644 (file)
@@ -60,6 +60,8 @@
 
 #define NETJSON_PROTOCOL "olsrv1"
 
+static struct json_session json_session;
+
 unsigned long long get_supported_commands_mask(void) {
   return SIW_NETJSON & ~(SIW_NETJSON_DEVICE_CONFIGURATION | SIW_NETJSON_DEVICE_MONITORING);
 }
@@ -92,13 +94,14 @@ const char * determine_mime_type(unsigned int send_what __attribute__((unused)))
 
 void output_start(struct autobuf *abuf) {
   /* global variables for tracking when to put a comma in for JSON */
-  abuf_json_reset_entry_number_and_depth();
-  abuf_json_mark_output(true, abuf);
+  abuf_json_reset_entry_number_and_depth(&json_session);
+  abuf_json_mark_output(&json_session, true, abuf);
 }
 
 void output_end(struct autobuf *abuf) {
-  abuf_json_mark_output(false, abuf);
+  abuf_json_mark_output(&json_session, false, abuf);
   abuf_puts(abuf, "\n");
+  abuf_json_reset_entry_number_and_depth(&json_session);
 }
 
 void output_error(struct autobuf *abuf, unsigned int status, const char * req __attribute__((unused)), bool http_headers) {
@@ -113,7 +116,7 @@ void output_error(struct autobuf *abuf, unsigned int status, const char * req __
   if (status == INFO_HTTP_NOCONTENT) {
     /* do nothing */
   } else {
-    abuf_json_string(abuf, "error", httpStatusToReply(status));
+    abuf_json_string(&json_session, abuf, "error", httpStatusToReply(status));
   }
 
   output_end(abuf);
@@ -123,37 +126,37 @@ void ipc_print_network_routes(struct autobuf *abuf) {
   struct rt_entry *rt;
 
   /* mandatory */
-  abuf_json_string(abuf, "type", "NetworkRoutes");
-  abuf_json_string(abuf, "protocol", NETJSON_PROTOCOL);
-  abuf_json_string(abuf, "version", release_version);
-  abuf_json_string(abuf, "metric", olsr_cnf->lq_algorithm);
+  abuf_json_string(&json_session, abuf, "type", "NetworkRoutes");
+  abuf_json_string(&json_session, abuf, "protocol", NETJSON_PROTOCOL);
+  abuf_json_string(&json_session, abuf, "version", release_version);
+  abuf_json_string(&json_session, abuf, "metric", olsr_cnf->lq_algorithm);
 
   /* optional */
-  abuf_json_string(abuf, "revision", olsrd_version);
+  abuf_json_string(&json_session, abuf, "revision", olsrd_version);
   // topology_id
-  abuf_json_ip_address(abuf, "router_id", &olsr_cnf->main_addr);
+  abuf_json_ip_address(&json_session, abuf, "router_id", &olsr_cnf->main_addr);
 
   /* Walk the route table */
-  abuf_json_mark_object(true, true, abuf, "routes");
+  abuf_json_mark_object(&json_session, true, true, abuf, "routes");
   OLSR_FOR_ALL_RT_ENTRIES(rt) {
     if (rt->rt_best) {
       struct lqtextbuffer lqbuf;
 
-      abuf_json_mark_array_entry(true, abuf);
+      abuf_json_mark_array_entry(&json_session, true, abuf);
       /* mandatory */
-      abuf_json_prefix(abuf, "destination", &rt->rt_dst);
-      abuf_json_ip_address(abuf, "next", &rt->rt_best->rtp_nexthop.gateway);
-      abuf_json_string(abuf, "device", if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
-      abuf_json_float(abuf, "cost", get_linkcost_scaled(rt->rt_best->rtp_metric.cost, true));
+      abuf_json_prefix(&json_session, abuf, "destination", &rt->rt_dst);
+      abuf_json_ip_address(&json_session, abuf, "next", &rt->rt_best->rtp_nexthop.gateway);
+      abuf_json_string(&json_session, abuf, "device", if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
+      abuf_json_float(&json_session, abuf, "cost", get_linkcost_scaled(rt->rt_best->rtp_metric.cost, true));
 
       /* optional */
-      abuf_json_string(abuf, "cost_text", get_linkcost_text(rt->rt_best->rtp_metric.cost, true, &lqbuf));
+      abuf_json_string(&json_session, abuf, "cost_text", get_linkcost_text(rt->rt_best->rtp_metric.cost, true, &lqbuf));
       // source
 
-      abuf_json_mark_array_entry(false, abuf);
+      abuf_json_mark_array_entry(&json_session, false, abuf);
     }
   } OLSR_FOR_ALL_RT_ENTRIES_END(rt);
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL);
 }
 
 void ipc_print_network_graph(struct autobuf *abuf) {
@@ -167,15 +170,15 @@ void ipc_print_network_graph(struct autobuf *abuf) {
   avl_init(&nodes, (olsr_cnf->ip_version == AF_INET) ? avl_comp_ipv4 : avl_comp_ipv6);
 
   /* mandatory */
-  abuf_json_string(abuf, "type", "NetworkGraph");
-  abuf_json_string(abuf, "protocol", NETJSON_PROTOCOL);
-  abuf_json_string(abuf, "version", release_version);
-  abuf_json_string(abuf, "metric", olsr_cnf->lq_algorithm);
+  abuf_json_string(&json_session, abuf, "type", "NetworkGraph");
+  abuf_json_string(&json_session, abuf, "protocol", NETJSON_PROTOCOL);
+  abuf_json_string(&json_session, abuf, "version", release_version);
+  abuf_json_string(&json_session, abuf, "metric", olsr_cnf->lq_algorithm);
 
   /* optional */
-  abuf_json_string(abuf, "revision", olsrd_version);
+  abuf_json_string(&json_session, abuf, "revision", olsrd_version);
   // topology_id
-  abuf_json_ip_address(abuf, "router_id", &olsr_cnf->main_addr);
+  abuf_json_ip_address(&json_session, abuf, "router_id", &olsr_cnf->main_addr);
   // label
 
   /*
@@ -210,28 +213,28 @@ void ipc_print_network_graph(struct autobuf *abuf) {
    * Output Nodes
    */
 
-  abuf_json_mark_object(true, true, abuf, "nodes");
+  abuf_json_mark_object(&json_session, true, true, abuf, "nodes");
   while (nodes.count > 0) {
     struct avl_node *node = avl_walk_first(&nodes);
     struct node_entry *node_entry = avlnode2node(node);
 
     if (!node_entry->isAlias) {
-      abuf_json_mark_array_entry(true, abuf);
+      abuf_json_mark_array_entry(&json_session, true, abuf);
 
       /* mandatory */
-      abuf_json_ip_address(abuf, "id", node->key);
+      abuf_json_ip_address(&json_session, abuf, "id", node->key);
 
       /* optional */
       // label
       if (node_entry->mid) {
         struct mid_address * alias = node_entry->mid->aliases;
         if (alias) {
-          abuf_json_mark_object(true, true, abuf, "local_addresses");
+          abuf_json_mark_object(&json_session, true, true, abuf, "local_addresses");
           while (alias) {
-            abuf_json_ip_address(abuf, NULL, &alias->alias);
+            abuf_json_ip_address(&json_session, abuf, NULL, &alias->alias);
             alias = alias->next_alias;
           }
-          abuf_json_mark_object(false, true, abuf, NULL);
+          abuf_json_mark_object(&json_session, false, true, abuf, NULL);
         }
       } else if (node_entry->link) {
         /* no local_addresses */
@@ -240,7 +243,7 @@ void ipc_print_network_graph(struct autobuf *abuf) {
       }
       // properties
 
-      abuf_json_mark_array_entry(false, abuf);
+      abuf_json_mark_array_entry(&json_session, false, abuf);
     }
 
     if (node_entry == node_self) {
@@ -250,45 +253,45 @@ void ipc_print_network_graph(struct autobuf *abuf) {
     avl_delete(&nodes, node);
     free(node);
   }
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL);
 
   /*
    * Output Links
    */
 
-  abuf_json_mark_object(true, true, abuf, "links");
+  abuf_json_mark_object(&json_session, true, true, abuf, "links");
   OLSR_FOR_ALL_LINK_ENTRIES(link_entry) {
     struct lqtextbuffer lqbuf;
 
-    abuf_json_mark_array_entry(true, abuf);
+    abuf_json_mark_array_entry(&json_session, true, abuf);
 
     /* mandatory */
-    abuf_json_ip_address(abuf, "source", &link_entry->local_iface_addr);
-    abuf_json_ip_address(abuf, "target", &link_entry->neighbor_iface_addr);
-    abuf_json_float(abuf, "cost", get_linkcost_scaled(link_entry->linkcost, false));
+    abuf_json_ip_address(&json_session, abuf, "source", &link_entry->local_iface_addr);
+    abuf_json_ip_address(&json_session, abuf, "target", &link_entry->neighbor_iface_addr);
+    abuf_json_float(&json_session, abuf, "cost", get_linkcost_scaled(link_entry->linkcost, false));
 
     /* optional */
-    abuf_json_string(abuf, "cost_text", get_linkcost_text(link_entry->linkcost, false, &lqbuf));
+    abuf_json_string(&json_session, abuf, "cost_text", get_linkcost_text(link_entry->linkcost, false, &lqbuf));
     // properties
 
-    abuf_json_mark_array_entry(false, abuf);
+    abuf_json_mark_array_entry(&json_session, false, abuf);
   } OLSR_FOR_ALL_LINK_ENTRIES_END(my_link);
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL);
 }
 
 void ipc_print_network_collection(struct autobuf *abuf) {
   /* mandatory */
-  abuf_json_string(abuf, "type", "NetworkCollection");
+  abuf_json_string(&json_session, abuf, "type", "NetworkCollection");
 
-  abuf_json_mark_object(true, true, abuf, "collection");
+  abuf_json_mark_object(&json_session, true, true, abuf, "collection");
 
-  abuf_json_mark_array_entry(true, abuf);
+  abuf_json_mark_array_entry(&json_session, true, abuf);
   ipc_print_network_routes(abuf);
-  abuf_json_mark_array_entry(false, abuf);
+  abuf_json_mark_array_entry(&json_session, false, abuf);
 
-  abuf_json_mark_array_entry(true, abuf);
+  abuf_json_mark_array_entry(&json_session, true, abuf);
   ipc_print_network_graph(abuf);
-  abuf_json_mark_array_entry(false, abuf);
+  abuf_json_mark_array_entry(&json_session, false, abuf);
 
-  abuf_json_mark_object(false, true, abuf, NULL);
+  abuf_json_mark_object(&json_session, false, true, abuf, NULL);
 }