X-Git-Url: https://sigrok.org/gitweb/?p=libsigrokdecode.git;a=blobdiff_plain;f=controller.c;h=476f4f3aaf6b0e613d6a560f446302f6b5c4cb07;hp=e325e0a6208cf98248101673c0c9714c27ffdfc0;hb=55c3c5f4b9d38b85fae2c39a8a6150b4c50b1bdb;hpb=7a1712c4fd07f64222079acd5ec3fa3348a5cb15 diff --git a/controller.c b/controller.c index e325e0a..476f4f3 100644 --- a/controller.c +++ b/controller.c @@ -25,22 +25,20 @@ #include #include - /* List of decoder instances. */ static GSList *di_list = NULL; /* List of frontend callbacks to receive PD output. */ static GSList *callbacks = NULL; -/* lives in decoder.c */ -extern GSList *pd_list; - -/* lives in module_sigrokdecode.c */ -extern PyMODINIT_FUNC PyInit_sigrokdecode(void); +/* decoder.c */ +extern SRD_PRIV GSList *pd_list; -/* lives in type_logic.c */ -extern PyTypeObject srd_logic_type; +/* module_sigrokdecode.c */ +extern SRD_PRIV PyMODINIT_FUNC PyInit_sigrokdecode(void); +/* type_logic.c */ +extern SRD_PRIV PyTypeObject srd_logic_type; /** * Initialize libsigrokdecode. @@ -64,7 +62,7 @@ extern PyTypeObject srd_logic_type; * directory cannot be accessed, return SRD_ERR_DECODERS_DIR. * If not enough memory could be allocated, return SRD_ERR_MALLOC. */ -int srd_init(void) +SRD_API int srd_init(void) { int ret; @@ -89,7 +87,6 @@ int srd_init(void) return SRD_OK; } - /** * Shutdown libsigrokdecode. * @@ -102,9 +99,8 @@ int srd_init(void) * * @return SRD_OK upon success, a (negative) error code otherwise. */ -int srd_exit(void) +SRD_API int srd_exit(void) { - srd_dbg("Exiting libsigrokdecode."); srd_unload_all_decoders(); @@ -116,7 +112,6 @@ int srd_exit(void) return SRD_OK; } - /** * Add an additional search directory for the protocol decoders. * @@ -132,7 +127,7 @@ int srd_exit(void) * * @return TODO. */ -int set_modulepath(void) +SRD_API int set_modulepath(void) { int ret; gchar *path, *s; @@ -163,7 +158,6 @@ int set_modulepath(void) return ret; } - /** * Set options in a decoder instance. * @@ -174,8 +168,8 @@ int set_modulepath(void) * * @return SRD_OK upon success, a (negative) error code otherwise. */ -int srd_instance_set_options(struct srd_decoder_instance *di, - GHashTable *options) +SRD_API int srd_instance_set_options(struct srd_decoder_instance *di, + GHashTable *options) { PyObject *py_dec_options, *py_dec_optkeys, *py_di_options, *py_optval; PyObject *py_optlist, *py_classval; @@ -184,7 +178,7 @@ int srd_instance_set_options(struct srd_decoder_instance *di, int num_optkeys, ret, size, i; char *key, *value; - if(!PyObject_HasAttrString(di->decoder->py_dec, "options")) { + if (!PyObject_HasAttrString(di->decoder->py_dec, "options")) { /* Decoder has no options. */ if (g_hash_table_size(options) == 0) { /* No options provided. */ @@ -215,7 +209,8 @@ int srd_instance_set_options(struct srd_decoder_instance *di, if (!(py_classval = PyList_GetItem(py_optlist, 1))) goto err_out; if (!PyUnicode_Check(py_classval) && !PyLong_Check(py_classval)) { - srd_err("Options of type %s are not yet supported.", Py_TYPE(py_classval)->tp_name); + srd_err("Options of type %s are not yet supported.", + Py_TYPE(py_classval)->tp_name); goto err_out; } @@ -231,8 +226,9 @@ int srd_instance_set_options(struct srd_decoder_instance *di, if (!(py_optval = PyLong_FromString(value, NULL, 0))) { /* ValueError Exception */ PyErr_Clear(); - srd_err("Option %s has invalid value %s: expected integer.", - key, value); + srd_err("Option %s has invalid value " + "%s: expected integer.", + key, value); goto err_out; } } @@ -250,7 +246,8 @@ int srd_instance_set_options(struct srd_decoder_instance *di, if (val_ull == (unsigned long long)-1) { /* OverFlowError exception */ PyErr_Clear(); - srd_err("Invalid integer value for %s: expected integer.", key); + srd_err("Invalid integer value for %s: " + "expected integer.", key); goto err_out; } if (!(py_optval = PyLong_FromUnsignedLongLong(val_ull))) @@ -272,8 +269,7 @@ err_out: Py_XDECREF(py_di_options); Py_XDECREF(py_dec_optkeys); Py_XDECREF(py_dec_options); - if (key) - g_free(key); + g_free(key); if (PyErr_Occurred()) catch_exception("Stray exception in srd_instance_set_options()."); @@ -283,7 +279,6 @@ err_out: /* Helper GComparefunc for g_slist_find_custom() in srd_instance_set_probes() */ static gint compare_probe_id(struct srd_probe *a, char *probe_id) { - return strcmp(a->id, probe_id); } @@ -292,13 +287,12 @@ static gint compare_probe_id(struct srd_probe *a, char *probe_id) * * @param di Decoder instance. * @param probes A GHashTable of probes to set. Key is probe name, value is - * the probe number. Samples passed to this instance will be arranged in this - * order. - * + * the probe number. Samples passed to this instance will be + * arranged in this order. * @return SRD_OK upon success, a (negative) error code otherwise. */ -int srd_instance_set_probes(struct srd_decoder_instance *di, - GHashTable *new_probes) +SRD_API int srd_instance_set_probes(struct srd_decoder_instance *di, + GHashTable *new_probes) { GList *l; GSList *sl; @@ -306,14 +300,17 @@ int srd_instance_set_probes(struct srd_decoder_instance *di, int *new_probemap, new_probenum; char *probe_id, *probenum_str; + srd_dbg("set probes called for instance %s with list of %d probes", + di->instance_id, g_hash_table_size(new_probes)); + if (g_hash_table_size(new_probes) == 0) /* No probes provided. */ return SRD_OK; - if(di->dec_num_probes == 0) { + if (di->dec_num_probes == 0) { /* Decoder has no probes. */ srd_err("Protocol decoder %s has no probes to define.", - di->decoder->name); + di->decoder->name); return SRD_ERR_ARG; } @@ -329,7 +326,8 @@ int srd_instance_set_probes(struct srd_decoder_instance *di, probenum_str = g_hash_table_lookup(new_probes, probe_id); if (!probenum_str) { /* Probe name was specified without a value. */ - srd_err("No probe number was specified for %s.", probe_id); + srd_err("No probe number was specified for %s.", + probe_id); g_free(new_probemap); return SRD_ERR_ARG; } @@ -337,16 +335,18 @@ int srd_instance_set_probes(struct srd_decoder_instance *di, if (!(sl = g_slist_find_custom(di->decoder->probes, probe_id, (GCompareFunc)compare_probe_id))) { /* Fall back on optional probes. */ - if (!(sl = g_slist_find_custom(di->decoder->extra_probes, - probe_id, (GCompareFunc)compare_probe_id))) { - srd_err("Protocol decoder %s has no probe '%s'.", - di->decoder->name, probe_id); + if (!(sl = g_slist_find_custom(di->decoder->opt_probes, + probe_id, (GCompareFunc) compare_probe_id))) { + srd_err("Protocol decoder %s has no probe " + "'%s'.", di->decoder->name, probe_id); g_free(new_probemap); return SRD_ERR_ARG; } } p = sl->data; new_probemap[p->order] = new_probenum; + srd_dbg("setting probe mapping for %d = probe %d", p->order, + new_probenum); } g_free(di->dec_probemap); di->dec_probemap = new_probemap; @@ -359,16 +359,16 @@ int srd_instance_set_probes(struct srd_decoder_instance *di, * * @param id Decoder 'id' field. * @param options GHashtable of options which override the defaults set in - * the decoder class. + * the decoder class. * @return Pointer to a newly allocated struct srd_decoder_instance, or - * NULL in case of failure. + * NULL in case of failure. */ -struct srd_decoder_instance *srd_instance_new(const char *decoder_id, - GHashTable *options) +SRD_API struct srd_decoder_instance *srd_instance_new(const char *decoder_id, + GHashTable *options) { + int i; struct srd_decoder *dec; struct srd_decoder_instance *di; - int i; char *instance_id; srd_dbg("Creating new %s instance.", decoder_id); @@ -392,9 +392,10 @@ struct srd_decoder_instance *srd_instance_new(const char *decoder_id, * order in which the decoder class defined them. */ di->dec_num_probes = g_slist_length(di->decoder->probes) + - g_slist_length(di->decoder->extra_probes); + g_slist_length(di->decoder->opt_probes); if (di->dec_num_probes) { - if (!(di->dec_probemap = g_try_malloc(sizeof(int) * di->dec_num_probes))) { + if (!(di->dec_probemap = + g_try_malloc(sizeof(int) * di->dec_num_probes))) { srd_err("Failed to malloc probe map."); g_free(di); return NULL; @@ -406,7 +407,8 @@ struct srd_decoder_instance *srd_instance_new(const char *decoder_id, /* Create a new instance of this decoder class. */ if (!(di->py_instance = PyObject_CallObject(dec->py_dec, NULL))) { if (PyErr_Occurred()) - catch_exception("failed to create %s instance: ", decoder_id); + catch_exception("failed to create %s instance: ", + decoder_id); g_free(di->dec_probemap); g_free(di); return NULL; @@ -424,10 +426,9 @@ struct srd_decoder_instance *srd_instance_new(const char *decoder_id, return di; } -int srd_instance_stack(struct srd_decoder_instance *di_from, - struct srd_decoder_instance *di_to) +SRD_API int srd_instance_stack(struct srd_decoder_instance *di_from, + struct srd_decoder_instance *di_to) { - if (!di_from || !di_to) { srd_err("Invalid from/to instance pair."); return SRD_ERR_ARG; @@ -453,7 +454,7 @@ int srd_instance_stack(struct srd_decoder_instance *di_from, * * @return Pointer to struct srd_decoder_instance, or NULL if not found. */ -struct srd_decoder_instance *srd_instance_find_by_id(char *instance_id) +SRD_API struct srd_decoder_instance *srd_instance_find_by_id(char *instance_id) { GSList *l; struct srd_decoder_instance *tmp, *di; @@ -482,8 +483,8 @@ struct srd_decoder_instance *srd_instance_find_by_id(char *instance_id) * * @return Pointer to struct srd_decoder_instance, or NULL if not found. */ -struct srd_decoder_instance *srd_instance_find_by_obj(GSList *stack, - PyObject *obj) +SRD_API struct srd_decoder_instance *srd_instance_find_by_obj(GSList *stack, + PyObject *obj) { GSList *l; struct srd_decoder_instance *tmp, *di; @@ -500,7 +501,7 @@ struct srd_decoder_instance *srd_instance_find_by_obj(GSList *stack, return di; } -int srd_instance_start(struct srd_decoder_instance *di, PyObject *args) +SRD_API int srd_instance_start(struct srd_decoder_instance *di, PyObject *args) { PyObject *py_name, *py_res; GSList *l; @@ -511,13 +512,15 @@ int srd_instance_start(struct srd_decoder_instance *di, PyObject *args) if (!(py_name = PyUnicode_FromString("start"))) { srd_err("Unable to build python object for 'start'."); - catch_exception("Protocol decoder instance %s: ", di->instance_id); + catch_exception("Protocol decoder instance %s: ", + di->instance_id); return SRD_ERR_PYTHON; } if (!(py_res = PyObject_CallMethodObjArgs(di->py_instance, - py_name, args, NULL))) { - catch_exception("Protocol decoder instance %s: ", di->instance_id); + py_name, args, NULL))) { + catch_exception("Protocol decoder instance %s: ", + di->instance_id); return SRD_ERR_PYTHON; } @@ -547,8 +550,9 @@ int srd_instance_start(struct srd_decoder_instance *di, PyObject *args) * * @return SRD_OK upon success, a (negative) error code otherwise. */ -int srd_instance_decode(uint64_t start_samplenum, - struct srd_decoder_instance *di, uint8_t *inbuf, uint64_t inbuflen) +SRD_API int srd_instance_decode(uint64_t start_samplenum, + struct srd_decoder_instance *di, + uint8_t *inbuf, uint64_t inbuflen) { PyObject *py_res; srd_logic *logic; @@ -587,8 +591,10 @@ int srd_instance_decode(uint64_t start_samplenum, Py_IncRef(di->py_instance); end_samplenum = start_samplenum + inbuflen / di->data_unitsize; if (!(py_res = PyObject_CallMethod(di->py_instance, "decode", - "KKO", logic->start_samplenum, end_samplenum, logic))) { - catch_exception("Protocol decoder instance %s: ", di->instance_id); + "KKO", logic->start_samplenum, + end_samplenum, logic))) { + catch_exception("Protocol decoder instance %s: ", + di->instance_id); return SRD_ERR_PYTHON; /* TODO: More specific error? */ } Py_DecRef(py_res); @@ -596,8 +602,44 @@ int srd_instance_decode(uint64_t start_samplenum, return SRD_OK; } +SRD_API void srd_instance_free(struct srd_decoder_instance *di) +{ + GSList *l; + struct srd_pd_output *pdo; + + srd_dbg("Freeing instance %s", di->instance_id); -int srd_session_start(int num_probes, int unitsize, uint64_t samplerate) + Py_DecRef(di->py_instance); + g_free(di->instance_id); + g_free(di->dec_probemap); + g_slist_free(di->next_di); + for (l = di->pd_output; l; l = l->next) { + pdo = l->data; + g_free(pdo->proto_id); + g_free(pdo); + } + g_slist_free(di->pd_output); +} + +SRD_API void srd_instance_free_all(GSList *stack) +{ + GSList *l; + struct srd_decoder_instance *di; + + di = NULL; + for (l = stack ? stack : di_list; di == NULL && l != NULL; l = l->next) { + di = l->data; + if (di->next_di) + srd_instance_free_all(di->next_di); + srd_instance_free(di); + } + if (!stack) { + g_slist_free(di_list); + di_list = NULL; + } +} + +SRD_API int srd_session_start(int num_probes, int unitsize, uint64_t samplerate) { PyObject *args; GSList *d; @@ -631,26 +673,26 @@ int srd_session_start(int num_probes, int unitsize, uint64_t samplerate) } /* Feed logic samples to decoder session. */ -int srd_session_feed(uint64_t start_samplenum, uint8_t *inbuf, uint64_t inbuflen) +SRD_API int srd_session_feed(uint64_t start_samplenum, uint8_t * inbuf, + uint64_t inbuflen) { GSList *d; int ret; srd_dbg("Calling decode() on all instances with starting sample " - "number %"PRIu64", %"PRIu64" bytes at 0x%p", start_samplenum, - inbuflen, inbuf); + "number %" PRIu64 ", %" PRIu64 " bytes at 0x%p", + start_samplenum, inbuflen, inbuf); for (d = di_list; d; d = d->next) { if ((ret = srd_instance_decode(start_samplenum, d->data, inbuf, - inbuflen)) != SRD_OK) + inbuflen)) != SRD_OK) return ret; } return SRD_OK; } - -int srd_register_callback(int output_type, void *cb) +SRD_API int srd_register_callback(int output_type, srd_pd_output_callback_t cb) { struct srd_pd_callback *pd_cb; @@ -666,7 +708,7 @@ int srd_register_callback(int output_type, void *cb) return SRD_OK; } -void *srd_find_callback(int output_type) +SRD_API void *srd_find_callback(int output_type) { GSList *l; struct srd_pd_callback *pd_cb; @@ -684,9 +726,9 @@ void *srd_find_callback(int output_type) return cb; } - /* This is the backend function to python sigrokdecode.add() call. */ -int pd_add(struct srd_decoder_instance *di, int output_type, char *proto_id) +SRD_PRIV int pd_add(struct srd_decoder_instance *di, int output_type, + char *proto_id) { struct srd_pd_output *pdo; @@ -705,4 +747,3 @@ int pd_add(struct srd_decoder_instance *di, int output_type, char *proto_id) return pdo->pdo_id; } -