+static int
+vl_msg_api_trace_write_one (api_main_t *am, u8 *msg, FILE *fp)
+{
+ u8 *tmpmem = 0;
+ int tlen, slen;
+ cJSON *(*tojson_fn) (void *);
+
+ u32 msg_length = vec_len (msg);
+ vec_validate (tmpmem, msg_length - 1);
+ clib_memcpy_fast (tmpmem, msg, msg_length);
+ u16 id = clib_net_to_host_u16 (*((u16 *) msg));
+
+ void (*endian_fp) (void *);
+ endian_fp = am->msg_endian_handlers[id];
+ (*endian_fp) (tmpmem);
+
+ if (id < vec_len (am->msg_tojson_handlers) && am->msg_tojson_handlers[id])
+ {
+ tojson_fn = am->msg_tojson_handlers[id];
+ cJSON *o = tojson_fn (tmpmem);
+ char *s = cJSON_Print (o);
+ slen = strlen (s);
+ tlen = fwrite (s, 1, slen, fp);
+ cJSON_free (s);
+ cJSON_Delete (o);
+ vec_free (tmpmem);
+ if (tlen != slen)
+ {
+ fformat (stderr, "writing to file error\n");
+ return -11;
+ }
+ }
+ else
+ fformat (stderr, " [no registered tojson fn]\n");
+
+ return 0;
+}
+
+#define vl_msg_fwrite(_s, _f) fwrite (_s, 1, sizeof (_s) - 1, _f)
+
+typedef struct
+{
+ FILE *fp;
+ u32 n_traces;
+ u32 i;
+} vl_msg_write_json_args_t;
+
+static int
+vl_msg_write_json_fn (u8 *msg, void *ctx)
+{
+ vl_msg_write_json_args_t *arg = ctx;
+ FILE *fp = arg->fp;
+ api_main_t *am = vlibapi_get_main ();
+ int rc = vl_msg_api_trace_write_one (am, msg, fp);
+ if (rc < 0)
+ return rc;
+
+ if (arg->i < arg->n_traces - 1)
+ vl_msg_fwrite (",\n", fp);
+ arg->i++;
+ return 0;
+}
+
+static int
+vl_msg_api_trace_write_json (api_main_t *am, vl_api_trace_t *tp, FILE *fp)
+{
+ vl_msg_write_json_args_t args;
+ clib_memset (&args, 0, sizeof (args));
+ args.fp = fp;
+ args.n_traces = vec_len (tp->traces);
+ vl_msg_fwrite ("[\n", fp);
+
+ int rv = vl_msg_traverse_trace (tp, vl_msg_write_json_fn, &args);
+ if (rv < 0)
+ return rv;
+
+ vl_msg_fwrite ("]", fp);
+ return 0;
+}
+