From 983cb0f5b49167328864d0878148a7407becd1c0 Mon Sep 17 00:00:00 2001 From: Bert Vermeulen Date: Sun, 8 Jan 2012 03:20:12 +0100 Subject: [PATCH] pass PD output to the calling frontend, simple annotation viewer in CLI. --- controller.c | 34 +++++++++++++++++++++++++++++++ module_sigrokdecode.c | 47 ++++++++++++++++++++++++------------------- sigrokdecode.h | 16 +++++++++++---- 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/controller.c b/controller.c index 19dc252..f7ffb25 100644 --- a/controller.c +++ b/controller.c @@ -24,6 +24,8 @@ #include +static GSList *callbacks = NULL; + /* TODO static GSList *pipelines = NULL; struct srd_pipeline { @@ -326,6 +328,38 @@ struct srd_decoder_instance *get_di_by_decobject(void *decobject) return NULL; } +int srd_register_callback(int output_type, void *cb) +{ + struct srd_pd_callback *pd_cb; + + if (!(pd_cb = g_try_malloc(sizeof(struct srd_pd_callback)))) + return SRD_ERR_MALLOC; + + pd_cb->output_type = output_type; + pd_cb->callback = cb; + callbacks = g_slist_append(callbacks, pd_cb); + + printf("got cb for %d: %p\n", output_type, cb); + return SRD_OK; +} + +void *srd_find_callback(int output_type) +{ + GSList *l; + struct srd_pd_callback *pd_cb; + void *(cb); + + cb = NULL; + for (l = callbacks; l; l = l->next) { + pd_cb = l->data; + if (pd_cb->output_type == output_type) { + cb = pd_cb->callback; + break; + } + } + + return cb; +} //int srd_pipeline_new(int plid) //{ diff --git a/module_sigrokdecode.c b/module_sigrokdecode.c index 9c8c72e..e92c9e7 100644 --- a/module_sigrokdecode.c +++ b/module_sigrokdecode.c @@ -95,14 +95,15 @@ static PyObject *Decoder_put(PyObject *self, PyObject *args) PyObject *data; struct srd_decoder_instance *di; struct srd_pd_output *pdo; - uint64_t timeoffset, duration; - int output_id, annotation_format, i; - char **annotation, **ann_info; + struct srd_protocol_data *pdata; + uint64_t start_sample, end_sample; + int output_id; + void (*cb)(); if (!(di = get_di_by_decobject(self))) return NULL; - if (!PyArg_ParseTuple(args, "KKiO", &timeoffset, &duration, &output_id, &data)) + if (!PyArg_ParseTuple(args, "KKiO", &start_sample, &end_sample, &output_id, &data)) return NULL; if (!(l = g_slist_nth(di->pd_output, output_id))) { @@ -114,31 +115,35 @@ static PyObject *Decoder_put(PyObject *self, PyObject *args) switch (pdo->output_type) { case SRD_OUTPUT_ANNOTATION: - if (convert_pyobj(di, data, &annotation_format, &annotation) != SRD_OK) - return NULL; - - /* TODO: SRD_OUTPUT_ANNOTATION should go back up to the caller */ - ann_info = g_slist_nth_data(pdo->decoder->annotation, annotation_format); - printf("annotation format %d (%s): ", annotation_format, ann_info[0]); - for (i = 0; annotation[i]; i++) - printf("\"%s\" ", annotation[i]); - printf("\n"); - break; - case SRD_OUTPUT_PROTOCOL: - - /* TODO: SRD_OUTPUT_PROTOCOL should go up the PD stack. */ - printf("%s protocol data: ", pdo->protocol_id); - PyObject_Print(data, stdout, Py_PRINT_RAW); - puts(""); + case SRD_OUTPUT_BINARY: break; - default: srd_err("Protocol decoder %s submitted invalid output type %d", di->decoder->name, pdo->output_type); + return NULL; break; } + if ((cb = srd_find_callback(pdo->output_type))) { + /* Something registered an interest in this output type. */ + if (!(pdata = g_try_malloc0(sizeof(struct srd_protocol_data)))) + return NULL; + pdata->start_sample = start_sample; + pdata->end_sample = end_sample; + pdata->pdo = pdo; + if (pdo->output_type == SRD_OUTPUT_ANNOTATION) { + /* annotations need converting from PyObject */ + if (convert_pyobj(di, data, &pdata->annotation_format, + (char ***)&pdata->data) != SRD_OK) + return NULL; + } else { + /* annotation_format is unused, data is an opaque blob. */ + pdata->data = data; + } + cb(pdata); + } + Py_RETURN_NONE; } diff --git a/sigrokdecode.h b/sigrokdecode.h index a6641d4..85845c9 100644 --- a/sigrokdecode.h +++ b/sigrokdecode.h @@ -67,8 +67,10 @@ enum { SRD_OUTPUT_ANNOTATION, SRD_OUTPUT_PROTOCOL, SRD_OUTPUT_BINARY, - /* When adding an output type, don't forget to expose it to PDs - * in controller.c:PyInit_sigrokdecode() + /* When adding an output type, don't forget to expose it to PDs in: + * controller.c:PyInit_sigrokdecode() + * and add a check in: + * module_sigrokdecode.c:Decoder_put() */ }; @@ -150,10 +152,14 @@ struct srd_protocol_data { uint64_t start_sample; uint64_t end_sample; struct srd_pd_output *pdo; - int annotation_type; - unsigned char **data; + int annotation_format; + void *data; }; +struct srd_pd_callback { + int output_type; + void (*callback)(struct srd_protocol_data *); +}; /*--- controller.c ----------------------------------------------------------*/ @@ -172,6 +178,8 @@ int srd_session_feed(uint64_t timeoffset, uint64_t duration, uint8_t *inbuf, int pd_output_new(struct srd_decoder_instance *di, int output_type, char *output_id); struct srd_decoder_instance *get_di_by_decobject(void *decobject); +int srd_register_callback(int output_type, void *cb); +void *srd_find_callback(int output_type); /*--- decoder.c -------------------------------------------------------------*/ -- 2.30.2