}
/* All modules must provide a data or recv API callback. */
- if (!outputs[i]->data && !outputs[i]->recv) {
- sr_err("No data/recv in module %d ('%s').", i, d);
+ if (!outputs[i]->data && !outputs[i]->receive) {
+ sr_err("No data/receive in module %d ('%s').", i, d);
errors++;
}
* <code>data_out</code> parameter, so the caller knows not to try
* and g_free() it.
*
- * Note: This API call is obsolete, use recv() instead.
+ * Note: This API call is obsolete, use receive() instead.
*
* @param o Pointer to the respective 'struct sr_output'.
* @param data_in Pointer to the input data buffer.
* it stored in the <code>data_out</code> and <code>length_out</code>
* parameters, or NULL if no output was generated.
*
- * Note: This API call is obsolete, use recv() instead.
+ * Note: This API call is obsolete, use receive() instead.
*
* @param o Pointer to the respective 'struct sr_output'.
* @param event_type Type of event that occured.
* @return SR_OK upon success, a negative error code otherwise.
*/
int (*event) (struct sr_output *o, int event_type, uint8_t **data_out,
- uint64_t *length_out);
+ uint64_t *length_out);
- GString *(*recv) (struct sr_output *o, const struct sr_dev_inst *sdi,
- const struct sr_datafeed_packet *packet);
+ /**
+ * This function is passed a copy of every packed in the data feed.
+ * Any output generated by the output module in response to the
+ * packet should be returned in a newly allocated GString
+ * <code>out</code>, which will be freed by the caller.
+ *
+ * Packets not of interest to the output module can just be ignored,
+ * and the <code>out</code> parameter set to NULL.
+ *
+ * @param o Pointer to the respective 'struct sr_output'.
+ * @param sdi The device instance that generated the packet.
+ * @param packet The complete packet.
+ * @param out A pointer where a GString * should be stored if
+ * the module generates output, or NULL if not.
+ *
+ * @return SR_OK upon success, a negative error code otherwise.
+ */
+ int (*receive) (struct sr_output *o, const struct sr_dev_inst *sdi,
+ const struct sr_datafeed_packet *packet, GString **out);
+ /**
+ * This function is called after the caller is finished using
+ * the output module, and can be used to free any internal
+ * resources the module may keep.
+ *
+ * @return SR_OK upon success, a negative error code otherwise.
+ */
int (*cleanup) (struct sr_output *o);
};
struct context {
int num_enabled_probes;
GPtrArray *probelist;
- GString *out;
};
static int init(struct sr_output *o)
ctx->num_enabled_probes++;
}
- ctx->out = g_string_sized_new(512);
-
return SR_OK;
}
g_string_append_c(out, '\n');
}
-static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi,
- const struct sr_datafeed_packet *packet)
+static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
+ const struct sr_datafeed_packet *packet, GString **out)
{
- struct context *ctx;
const struct sr_datafeed_analog *analog;
struct sr_probe *probe;
GSList *l;
(void)sdi;
+ *out = NULL;
if (!o || !o->sdi)
- return NULL;
- ctx = o->internal;
+ return SR_ERR_ARG;
- g_string_set_size(ctx->out, 0);
switch (packet->type) {
- case SR_DF_HEADER:
- break;
case SR_DF_FRAME_BEGIN:
- g_string_append_printf(ctx->out, "FRAME-BEGIN\n");
+ *out = g_string_new("FRAME-BEGIN\n");
break;
case SR_DF_FRAME_END:
- g_string_append_printf(ctx->out, "FRAME-END\n");
+ *out = g_string_new("FRAME-END\n");
break;
case SR_DF_ANALOG:
analog = packet->payload;
fdata = (const float *)analog->data;
+ *out = g_string_sized_new(512);
for (i = 0; i < analog->num_samples; i++) {
for (l = analog->probes, p = 0; l; l = l->next, p++) {
probe = l->data;
- g_string_append_printf(ctx->out, "%s: ", probe->name);
+ g_string_append_printf(*out, "%s: ", probe->name);
fancyprint(analog->unit, analog->mqflags,
- fdata[i + p], ctx->out);
+ fdata[i + p], *out);
}
}
break;
}
- return ctx->out;
+ return SR_OK;
}
static int cleanup(struct sr_output *o)
ctx = o->internal;
g_ptr_array_free(ctx->probelist, 1);
- g_string_free(ctx->out, 1);
g_free(ctx);
o->internal = NULL;
.description = "Analog data",
.df_type = SR_DF_ANALOG,
.init = init,
- .recv = receive,
+ .receive = receive,
.cleanup = cleanup
};
#define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args)
struct context {
- uint64_t samplerate;
+ uint64_t samplerate;
uint64_t num_samples;
};
}
o->internal = ctx;
- ctx->samplerate = 0;
+ ctx->samplerate = 0;
ctx->num_samples = 0;
return SR_OK;
GVariant *gvar;
int num_enabled_probes;
- if (!ctx->samplerate && sr_config_get(sdi->driver, SR_CONF_SAMPLERATE,
+ if (!ctx->samplerate && sr_config_get(sdi->driver, SR_CONF_SAMPLERATE,
&gvar, sdi) == SR_OK) {
ctx->samplerate = g_variant_get_uint64(gvar);
g_variant_unref(gvar);
return s;
}
-static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi,
- const struct sr_datafeed_packet *packet)
+static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
+ const struct sr_datafeed_packet *packet, GString **out)
{
struct context *ctx;
const struct sr_datafeed_meta *meta;
const struct sr_datafeed_logic *logic;
const struct sr_config *src;
GSList *l;
- GString *out;
unsigned int i, j;
uint8_t c;
+ *out = NULL;
if (!o || !o->sdi)
- return NULL;
+ return SR_ERR_ARG;
ctx = o->internal;
- out = NULL;
switch (packet->type) {
- case SR_DF_META:
+ case SR_DF_META:
meta = packet->payload;
for (l = meta->config; l; l = l->next) {
src = l->data;
if (src->key == SR_CONF_SAMPLERATE)
ctx->samplerate = g_variant_get_uint64(src->data);
}
- break;
- case SR_DF_LOGIC:
+ break;
+ case SR_DF_LOGIC:
logic = packet->payload;
if (ctx->num_samples == 0) {
/* First logic packet in the feed. */
- out = gen_header(sdi, ctx);
+ *out = gen_header(sdi, ctx);
} else
- out = g_string_sized_new(512);
+ *out = g_string_sized_new(512);
for (i = 0; i <= logic->length - logic->unitsize; i += logic->unitsize) {
for (j = 0; j < logic->unitsize; j++) {
/* The OLS format wants the samples presented MSB first. */
c = *((uint8_t *)logic->data + i + logic->unitsize - 1 - j);
- g_string_append_printf(out, "%02x", c);
+ g_string_append_printf(*out, "%02x", c);
}
- g_string_append_printf(out, "@%"PRIu64"\n", ctx->num_samples++);
+ g_string_append_printf(*out, "@%"PRIu64"\n", ctx->num_samples++);
}
break;
}
- return out;
+ return SR_OK;
}
static int cleanup(struct sr_output *o)
return SR_ERR_ARG;
ctx = o->internal;
- g_free(ctx);
- o->internal = NULL;
+ g_free(ctx);
+ o->internal = NULL;
return SR_OK;
}
.description = "OpenBench Logic Sniffer",
.df_type = SR_DF_LOGIC,
.init = init,
- .recv = receive,
+ .receive = receive,
.cleanup = cleanup
};
return SR_OK;
}
-static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi,
- const struct sr_datafeed_packet *packet)
+static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
+ const struct sr_datafeed_packet *packet, GString **out)
{
const struct sr_datafeed_logic *logic;
struct context *ctx;
- GString *text;
unsigned int i;
int p, curbit, prevbit, index;
uint8_t *sample;
(void)sdi;
+ *out = NULL;
if (!o || !o->internal)
- return NULL;
+ return SR_ERR_ARG;
ctx = o->internal;
if (packet->type == SR_DF_END) {
- text = g_string_sized_new(16);
- g_string_printf(text, "$dumpoff\n$end\n");
- return text;
+ *out = g_string_new("$dumpoff\n$end\n");
+ return SR_OK;
} else if (packet->type != SR_DF_LOGIC)
- return NULL;
+ return SR_OK;
if (ctx->header) {
/* The header is still here, this must be the first packet. */
- text = ctx->header;
+ *out = ctx->header;
ctx->header = NULL;
} else {
- text = g_string_sized_new(512);
+ *out = g_string_sized_new(512);
}
logic = packet->payload;
continue;
/* Output which signal changed to which value. */
- g_string_append_printf(text, "#%" PRIu64 "\n%i%c\n",
+ g_string_append_printf(*out, "#%" PRIu64 "\n%i%c\n",
(uint64_t)(((float)samplecount / ctx->samplerate)
* ctx->period), curbit, (char)('!' + p));
}
memcpy(ctx->prevsample, sample, ctx->unitsize);
}
- return text;
+ return SR_OK;
}
static int cleanup(struct sr_output *o)
.description = "Value Change Dump (VCD)",
.df_type = SR_DF_LOGIC,
.init = init,
- .recv = receive,
+ .receive = receive,
.cleanup = cleanup,
};