]> sigrok.org Git - libsigrokdecode.git/blob - type_decoder.c
cff242c79999e83d3095dbb1293c0d501cc1bada
[libsigrokdecode.git] / type_decoder.c
1 /*
2  * This file is part of the libsigrokdecode project.
3  *
4  * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include "libsigrokdecode-internal.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
22 #include "libsigrokdecode.h"
23 #include <inttypes.h>
24
25 /** @cond PRIVATE */
26 extern SRD_PRIV GSList *sessions;
27 /** @endcond */
28
29 typedef struct {
30         PyObject_HEAD
31 } srd_Decoder;
32
33 /* This is only used for nicer srd_dbg() output. */
34 static const char *output_type_name(unsigned int idx)
35 {
36         static const char names[][16] = {
37                 "OUTPUT_ANN",
38                 "OUTPUT_PYTHON",
39                 "OUTPUT_BINARY",
40                 "OUTPUT_META",
41                 "(invalid)"
42         };
43
44         return names[MIN(idx, G_N_ELEMENTS(names) - 1)];
45 }
46
47 static void release_annotation(struct srd_proto_data_annotation *pda)
48 {
49         if (!pda)
50                 return;
51         if (pda->ann_text)
52                 g_strfreev(pda->ann_text);
53         g_free(pda);
54 }
55
56 static int convert_annotation(struct srd_decoder_inst *di, PyObject *obj,
57                 struct srd_proto_data *pdata)
58 {
59         PyObject *py_tmp;
60         struct srd_pd_output *pdo;
61         struct srd_proto_data_annotation *pda;
62         int ann_class;
63         char **ann_text;
64         PyGILState_STATE gstate;
65
66         gstate = PyGILState_Ensure();
67
68         /* Should be a list of [annotation class, [string, ...]]. */
69         if (!PyList_Check(obj)) {
70                 srd_err("Protocol decoder %s submitted an annotation that"
71                         " is not a list", di->decoder->name);
72                 goto err;
73         }
74
75         /* Should have 2 elements. */
76         if (PyList_Size(obj) != 2) {
77                 srd_err("Protocol decoder %s submitted annotation list with "
78                         "%zd elements instead of 2", di->decoder->name,
79                         PyList_Size(obj));
80                 goto err;
81         }
82
83         /*
84          * The first element should be an integer matching a previously
85          * registered annotation class.
86          */
87         py_tmp = PyList_GetItem(obj, 0);
88         if (!PyLong_Check(py_tmp)) {
89                 srd_err("Protocol decoder %s submitted annotation list, but "
90                         "first element was not an integer.", di->decoder->name);
91                 goto err;
92         }
93         ann_class = PyLong_AsLong(py_tmp);
94         if (!(pdo = g_slist_nth_data(di->decoder->annotations, ann_class))) {
95                 srd_err("Protocol decoder %s submitted data to unregistered "
96                         "annotation class %d.", di->decoder->name, ann_class);
97                 goto err;
98         }
99
100         /* Second element must be a list. */
101         py_tmp = PyList_GetItem(obj, 1);
102         if (!PyList_Check(py_tmp)) {
103                 srd_err("Protocol decoder %s submitted annotation list, but "
104                         "second element was not a list.", di->decoder->name);
105                 goto err;
106         }
107         if (py_strseq_to_char(py_tmp, &ann_text) != SRD_OK) {
108                 srd_err("Protocol decoder %s submitted annotation list, but "
109                         "second element was malformed.", di->decoder->name);
110                 goto err;
111         }
112
113         pda = g_malloc(sizeof(struct srd_proto_data_annotation));
114         pda->ann_class = ann_class;
115         pda->ann_text = ann_text;
116         pdata->data = pda;
117
118         PyGILState_Release(gstate);
119
120         return SRD_OK;
121
122 err:
123         PyGILState_Release(gstate);
124
125         return SRD_ERR_PYTHON;
126 }
127
128 static void release_binary(struct srd_proto_data_binary *pdb)
129 {
130         if (!pdb)
131                 return;
132         g_free((void *)pdb->data);
133         g_free(pdb);
134 }
135
136 static int convert_binary(struct srd_decoder_inst *di, PyObject *obj,
137                 struct srd_proto_data *pdata)
138 {
139         struct srd_proto_data_binary *pdb;
140         PyObject *py_tmp;
141         Py_ssize_t size;
142         int bin_class;
143         char *class_name, *buf;
144         PyGILState_STATE gstate;
145
146         gstate = PyGILState_Ensure();
147
148         /* Should be a list of [binary class, bytes]. */
149         if (!PyList_Check(obj)) {
150                 srd_err("Protocol decoder %s submitted non-list for SRD_OUTPUT_BINARY.",
151                         di->decoder->name);
152                 goto err;
153         }
154
155         /* Should have 2 elements. */
156         if (PyList_Size(obj) != 2) {
157                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list "
158                                 "with %zd elements instead of 2", di->decoder->name,
159                                 PyList_Size(obj));
160                 goto err;
161         }
162
163         /* The first element should be an integer. */
164         py_tmp = PyList_GetItem(obj, 0);
165         if (!PyLong_Check(py_tmp)) {
166                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, "
167                         "but first element was not an integer.", di->decoder->name);
168                 goto err;
169         }
170         bin_class = PyLong_AsLong(py_tmp);
171         if (!(class_name = g_slist_nth_data(di->decoder->binary, bin_class))) {
172                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY with "
173                         "unregistered binary class %d.", di->decoder->name, bin_class);
174                 goto err;
175         }
176
177         /* Second element should be bytes. */
178         py_tmp = PyList_GetItem(obj, 1);
179         if (!PyBytes_Check(py_tmp)) {
180                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, "
181                         "but second element was not bytes.", di->decoder->name);
182                 goto err;
183         }
184
185         /* Consider an empty set of bytes a bug. */
186         if (PyBytes_Size(py_tmp) == 0) {
187                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY "
188                                 "with empty data set.", di->decoder->name);
189                 goto err;
190         }
191
192         if (PyBytes_AsStringAndSize(py_tmp, &buf, &size) == -1)
193                 goto err;
194
195         PyGILState_Release(gstate);
196
197         pdb = g_malloc(sizeof(struct srd_proto_data_binary));
198         pdb->bin_class = bin_class;
199         pdb->size = size;
200         if (!(pdb->data = g_try_malloc(pdb->size))) {
201                 g_free(pdb);
202                 return SRD_ERR_MALLOC;
203         }
204         memcpy((void *)pdb->data, (const void *)buf, pdb->size);
205         pdata->data = pdb;
206
207         return SRD_OK;
208
209 err:
210         PyGILState_Release(gstate);
211
212         return SRD_ERR_PYTHON;
213 }
214
215 static inline struct srd_decoder_inst *srd_sess_inst_find_by_obj(
216         struct srd_session *sess, const GSList *stack, const PyObject *obj)
217 {
218         const GSList *l;
219         struct srd_decoder_inst *tmp, *di;
220
221         if (!sess)
222                 return NULL;
223
224         di = NULL;
225         for (l = stack ? stack : sess->di_list; di == NULL && l != NULL; l = l->next) {
226                 tmp = l->data;
227                 if (tmp->py_inst == obj)
228                         di = tmp;
229                 else if (tmp->next_di)
230                         di = srd_sess_inst_find_by_obj(sess, tmp->next_di, obj);
231         }
232
233         return di;
234 }
235
236 /**
237  * Find a decoder instance by its Python object.
238  *
239  * I.e. find that instance's instantiation of the sigrokdecode.Decoder class.
240  * This will recurse to find the instance anywhere in the stack tree of all
241  * sessions.
242  *
243  * @param stack Pointer to a GSList of struct srd_decoder_inst, indicating the
244  *              stack to search. To start searching at the bottom level of
245  *              decoder instances, pass NULL.
246  * @param obj The Python class instantiation.
247  *
248  * @return Pointer to struct srd_decoder_inst, or NULL if not found.
249  *
250  * @since 0.1.0
251  */
252 static inline struct srd_decoder_inst *srd_inst_find_by_obj(
253                 const GSList *stack, const PyObject *obj)
254 {
255         struct srd_decoder_inst *di;
256         struct srd_session *sess;
257         GSList *l;
258
259         di = NULL;
260         for (l = sessions; di == NULL && l != NULL; l = l->next) {
261                 sess = l->data;
262                 di = srd_sess_inst_find_by_obj(sess, stack, obj);
263         }
264
265         return di;
266 }
267
268 static int convert_meta(struct srd_proto_data *pdata, PyObject *obj)
269 {
270         long long intvalue;
271         double dvalue;
272         PyGILState_STATE gstate;
273
274         gstate = PyGILState_Ensure();
275
276         if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_INT64)) {
277                 if (!PyLong_Check(obj)) {
278                         PyErr_Format(PyExc_TypeError, "This output was registered "
279                                         "as 'int', but something else was passed.");
280                         goto err;
281                 }
282                 intvalue = PyLong_AsLongLong(obj);
283                 if (PyErr_Occurred())
284                         goto err;
285                 pdata->data = g_variant_new_int64(intvalue);
286         } else if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_DOUBLE)) {
287                 if (!PyFloat_Check(obj)) {
288                         PyErr_Format(PyExc_TypeError, "This output was registered "
289                                         "as 'float', but something else was passed.");
290                         goto err;
291                 }
292                 dvalue = PyFloat_AsDouble(obj);
293                 if (PyErr_Occurred())
294                         goto err;
295                 pdata->data = g_variant_new_double(dvalue);
296         }
297
298         PyGILState_Release(gstate);
299
300         return SRD_OK;
301
302 err:
303         PyGILState_Release(gstate);
304
305         return SRD_ERR_PYTHON;
306 }
307
308 static void release_meta(GVariant *gvar)
309 {
310         if (!gvar)
311                 return;
312         g_variant_unref(gvar);
313 }
314
315 static PyObject *Decoder_put(PyObject *self, PyObject *args)
316 {
317         GSList *l;
318         PyObject *py_data, *py_res;
319         struct srd_decoder_inst *di, *next_di;
320         struct srd_pd_output *pdo;
321         struct srd_proto_data pdata;
322         uint64_t start_sample, end_sample;
323         int output_id;
324         struct srd_pd_callback *cb;
325         PyGILState_STATE gstate;
326
327         py_data = NULL;
328
329         gstate = PyGILState_Ensure();
330
331         if (!(di = srd_inst_find_by_obj(NULL, self))) {
332                 /* Shouldn't happen. */
333                 srd_dbg("put(): self instance not found.");
334                 goto err;
335         }
336
337         if (!PyArg_ParseTuple(args, "KKiO", &start_sample, &end_sample,
338                 &output_id, &py_data)) {
339                 /*
340                  * This throws an exception, but by returning NULL here we let
341                  * Python raise it. This results in a much better trace in
342                  * controller.c on the decode() method call.
343                  */
344                 goto err;
345         }
346
347         if (!(l = g_slist_nth(di->pd_output, output_id))) {
348                 srd_err("Protocol decoder %s submitted invalid output ID %d.",
349                         di->decoder->name, output_id);
350                 goto err;
351         }
352         pdo = l->data;
353
354         srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s on oid %d.",
355                  di->inst_id, start_sample, end_sample,
356                  output_type_name(pdo->output_type), output_id);
357
358         pdata.start_sample = start_sample;
359         pdata.end_sample = end_sample;
360         pdata.pdo = pdo;
361         pdata.data = NULL;
362
363         switch (pdo->output_type) {
364         case SRD_OUTPUT_ANN:
365                 /* Annotations are only fed to callbacks. */
366                 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
367                         /* Convert from PyDict to srd_proto_data_annotation. */
368                         if (convert_annotation(di, py_data, &pdata) != SRD_OK) {
369                                 /* An error was already logged. */
370                                 break;
371                         }
372                         Py_BEGIN_ALLOW_THREADS
373                         cb->cb(&pdata, cb->cb_data);
374                         Py_END_ALLOW_THREADS
375                         release_annotation(pdata.data);
376                 }
377                 break;
378         case SRD_OUTPUT_PYTHON:
379                 for (l = di->next_di; l; l = l->next) {
380                         next_di = l->data;
381                         srd_spew("Sending %" PRIu64 "-%" PRIu64 " to instance %s",
382                                  start_sample, end_sample, next_di->inst_id);
383                         if (!(py_res = PyObject_CallMethod(
384                                 next_di->py_inst, "decode", "KKO", start_sample,
385                                 end_sample, py_data))) {
386                                 srd_exception_catch("Calling %s decode() failed",
387                                                         next_di->inst_id);
388                         }
389                         Py_XDECREF(py_res);
390                 }
391                 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
392                         /*
393                          * Frontends aren't really supposed to get Python
394                          * callbacks, but it's useful for testing.
395                          */
396                         pdata.data = py_data;
397                         cb->cb(&pdata, cb->cb_data);
398                 }
399                 break;
400         case SRD_OUTPUT_BINARY:
401                 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
402                         /* Convert from PyDict to srd_proto_data_binary. */
403                         if (convert_binary(di, py_data, &pdata) != SRD_OK) {
404                                 /* An error was already logged. */
405                                 break;
406                         }
407                         Py_BEGIN_ALLOW_THREADS
408                         cb->cb(&pdata, cb->cb_data);
409                         Py_END_ALLOW_THREADS
410                         release_binary(pdata.data);
411                 }
412                 break;
413         case SRD_OUTPUT_META:
414                 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
415                         /* Annotations need converting from PyObject. */
416                         if (convert_meta(&pdata, py_data) != SRD_OK) {
417                                 /* An exception was already set up. */
418                                 break;
419                         }
420                         Py_BEGIN_ALLOW_THREADS
421                         cb->cb(&pdata, cb->cb_data);
422                         Py_END_ALLOW_THREADS
423                         release_meta(pdata.data);
424                 }
425                 break;
426         default:
427                 srd_err("Protocol decoder %s submitted invalid output type %d.",
428                         di->decoder->name, pdo->output_type);
429                 break;
430         }
431
432         PyGILState_Release(gstate);
433
434         Py_RETURN_NONE;
435
436 err:
437         PyGILState_Release(gstate);
438
439         return NULL;
440 }
441
442 static PyObject *Decoder_register(PyObject *self, PyObject *args,
443                 PyObject *kwargs)
444 {
445         struct srd_decoder_inst *di;
446         struct srd_pd_output *pdo;
447         PyObject *py_new_output_id;
448         PyTypeObject *meta_type_py;
449         const GVariantType *meta_type_gv;
450         int output_type;
451         char *proto_id, *meta_name, *meta_descr;
452         char *keywords[] = { "output_type", "proto_id", "meta", NULL };
453         PyGILState_STATE gstate;
454         gboolean is_meta;
455         GSList *l;
456         struct srd_pd_output *cmp;
457
458         gstate = PyGILState_Ensure();
459
460         meta_type_py = NULL;
461         meta_type_gv = NULL;
462         meta_name = meta_descr = NULL;
463
464         if (!(di = srd_inst_find_by_obj(NULL, self))) {
465                 PyErr_SetString(PyExc_Exception, "decoder instance not found");
466                 goto err;
467         }
468
469         /* Default to instance ID, which defaults to class ID. */
470         proto_id = di->inst_id;
471         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|s(Oss)", keywords,
472                         &output_type, &proto_id,
473                         &meta_type_py, &meta_name, &meta_descr)) {
474                 /* Let Python raise this exception. */
475                 goto err;
476         }
477
478         /* Check if the meta value's type is supported. */
479         is_meta = output_type == SRD_OUTPUT_META;
480         if (is_meta) {
481                 if (meta_type_py == &PyLong_Type)
482                         meta_type_gv = G_VARIANT_TYPE_INT64;
483                 else if (meta_type_py == &PyFloat_Type)
484                         meta_type_gv = G_VARIANT_TYPE_DOUBLE;
485                 else {
486                         PyErr_Format(PyExc_TypeError, "Unsupported type.");
487                         goto err;
488                 }
489         }
490
491         pdo = NULL;
492         for (l = di->pd_output; l; l = l->next) {
493                 cmp = l->data;
494                 if (cmp->output_type != output_type)
495                         continue;
496                 if (strcmp(cmp->proto_id, proto_id) != 0)
497                         continue;
498                 if (is_meta && cmp->meta_type != meta_type_gv)
499                         continue;
500                 if (is_meta && strcmp(cmp->meta_name, meta_name) != 0)
501                         continue;
502                 if (is_meta && strcmp(cmp->meta_descr, meta_descr) != 0)
503                         continue;
504                 pdo = cmp;
505                 break;
506         }
507         if (pdo) {
508                 py_new_output_id = Py_BuildValue("i", pdo->pdo_id);
509                 PyGILState_Release(gstate);
510                 return py_new_output_id;
511         }
512
513         srd_dbg("Instance %s creating new output type %d for %s.",
514                 di->inst_id, output_type, proto_id);
515
516         pdo = g_malloc(sizeof(struct srd_pd_output));
517
518         /* pdo_id is just a simple index, nothing is deleted from this list anyway. */
519         pdo->pdo_id = g_slist_length(di->pd_output);
520         pdo->output_type = output_type;
521         pdo->di = di;
522         pdo->proto_id = g_strdup(proto_id);
523
524         if (output_type == SRD_OUTPUT_META) {
525                 pdo->meta_type = meta_type_gv;
526                 pdo->meta_name = g_strdup(meta_name);
527                 pdo->meta_descr = g_strdup(meta_descr);
528         }
529
530         di->pd_output = g_slist_append(di->pd_output, pdo);
531         py_new_output_id = Py_BuildValue("i", pdo->pdo_id);
532
533         PyGILState_Release(gstate);
534
535         return py_new_output_id;
536
537 err:
538         PyGILState_Release(gstate);
539
540         return NULL;
541 }
542
543 static int get_term_type(const char *v)
544 {
545         switch (v[0]) {
546         case 'h':
547                 return SRD_TERM_HIGH;
548         case 'l':
549                 return SRD_TERM_LOW;
550         case 'r':
551                 return SRD_TERM_RISING_EDGE;
552         case 'f':
553                 return SRD_TERM_FALLING_EDGE;
554         case 'e':
555                 return SRD_TERM_EITHER_EDGE;
556         case 'n':
557                 return SRD_TERM_NO_EDGE;
558         default:
559                 return -1;
560         }
561
562         return -1;
563 }
564
565 /**
566  * Get the pin values at the current sample number.
567  *
568  * @param di The decoder instance to use. Must not be NULL.
569  *           The number of channels must be >= 1.
570  *
571  * @return A newly allocated PyTuple containing the pin values at the
572  *         current sample number.
573  */
574 static PyObject *get_current_pinvalues(const struct srd_decoder_inst *di)
575 {
576         int i;
577         uint8_t sample;
578         const uint8_t *sample_pos;
579         int byte_offset, bit_offset;
580         PyObject *py_pinvalues;
581         PyGILState_STATE gstate;
582
583         if (!di) {
584                 srd_err("Invalid decoder instance.");
585                 return NULL;
586         }
587
588         gstate = PyGILState_Ensure();
589
590         py_pinvalues = PyTuple_New(di->dec_num_channels);
591
592         for (i = 0; i < di->dec_num_channels; i++) {
593                 /* A channelmap value of -1 means "unused optional channel". */
594                 if (di->dec_channelmap[i] == -1) {
595                         /* Value of unused channel is 0xff, instead of 0 or 1. */
596                         PyTuple_SetItem(py_pinvalues, i, PyLong_FromLong(0xff));
597                 } else {
598                         sample_pos = di->inbuf + ((di->abs_cur_samplenum - di->abs_start_samplenum) * di->data_unitsize);
599                         byte_offset = di->dec_channelmap[i] / 8;
600                         bit_offset = di->dec_channelmap[i] % 8;
601                         sample = *(sample_pos + byte_offset) & (1 << bit_offset) ? 1 : 0;
602                         PyTuple_SetItem(py_pinvalues, i, PyLong_FromLong(sample));
603                 }
604         }
605
606         PyGILState_Release(gstate);
607
608         return py_pinvalues;
609 }
610
611 /**
612  * Create a list of terms in the specified condition.
613  *
614  * If there are no terms in the condition, 'term_list' will be NULL.
615  *
616  * @param py_dict A Python dict containing terms. Must not be NULL.
617  * @param term_list Pointer to a GSList which will be set to the newly
618  *                  created list of terms. Must not be NULL.
619  *
620  * @return SRD_OK upon success, a negative error code otherwise.
621  */
622 static int create_term_list(PyObject *py_dict, GSList **term_list)
623 {
624         Py_ssize_t pos = 0;
625         PyObject *py_key, *py_value;
626         struct srd_term *term;
627         uint64_t num_samples_to_skip;
628         char *term_str;
629         PyGILState_STATE gstate;
630
631         if (!py_dict || !term_list)
632                 return SRD_ERR_ARG;
633
634         /* "Create" an empty GSList of terms. */
635         *term_list = NULL;
636
637         gstate = PyGILState_Ensure();
638
639         /* Iterate over all items in the current dict. */
640         while (PyDict_Next(py_dict, &pos, &py_key, &py_value)) {
641                 /* Check whether the current key is a string or a number. */
642                 if (PyLong_Check(py_key)) {
643                         /* The key is a number. */
644                         /* TODO: Check if the number is a valid channel. */
645                         /* Get the value string. */
646                         if ((py_pydictitem_as_str(py_dict, py_key, &term_str)) != SRD_OK) {
647                                 srd_err("Failed to get the value.");
648                                 goto err;
649                         }
650                         term = g_malloc(sizeof(struct srd_term));
651                         term->type = get_term_type(term_str);
652                         term->channel = PyLong_AsLong(py_key);
653                         g_free(term_str);
654                 } else if (PyUnicode_Check(py_key)) {
655                         /* The key is a string. */
656                         /* TODO: Check if it's "skip". */
657                         if ((py_pydictitem_as_long(py_dict, py_key, &num_samples_to_skip)) != SRD_OK) {
658                                 srd_err("Failed to get number of samples to skip.");
659                                 goto err;
660                         }
661                         term = g_malloc(sizeof(struct srd_term));
662                         term->type = SRD_TERM_SKIP;
663                         term->num_samples_to_skip = num_samples_to_skip;
664                         term->num_samples_already_skipped = 0;
665                 } else {
666                         srd_err("Term key is neither a string nor a number.");
667                         goto err;
668                 }
669
670                 /* Add the term to the list of terms. */
671                 *term_list = g_slist_append(*term_list, term);
672         }
673
674         PyGILState_Release(gstate);
675
676         return SRD_OK;
677
678 err:
679         PyGILState_Release(gstate);
680
681         return SRD_ERR;
682 }
683
684 /**
685  * Replace the current condition list with the new one.
686  *
687  * @param self TODO. Must not be NULL.
688  * @param args TODO. Must not be NULL.
689  *
690  * @retval SRD_OK The new condition list was set successfully.
691  * @retval SRD_ERR There was an error setting the new condition list.
692  *                 The contents of di->condition_list are undefined.
693  * @retval 9999 TODO.
694  */
695 static int set_new_condition_list(PyObject *self, PyObject *args)
696 {
697         struct srd_decoder_inst *di;
698         GSList *term_list;
699         PyObject *py_conditionlist, *py_conds, *py_dict;
700         int i, num_conditions, ret;
701         PyGILState_STATE gstate;
702
703         if (!self || !args)
704                 return SRD_ERR_ARG;
705
706         gstate = PyGILState_Ensure();
707
708         /* Get the decoder instance. */
709         if (!(di = srd_inst_find_by_obj(NULL, self))) {
710                 PyErr_SetString(PyExc_Exception, "decoder instance not found");
711                 goto err;
712         }
713
714         /*
715          * Return an error condition from .wait() when termination is
716          * requested, such that decode() will terminate.
717          */
718         if (di->want_wait_terminate) {
719                 srd_dbg("%s: %s: Skip (want_term).", di->inst_id, __func__);
720                 goto err;
721         }
722
723         /*
724          * Parse the argument of self.wait() into 'py_conds', and check
725          * the data type. The argument is optional, None is assumed in
726          * its absence. None or an empty dict or an empty list mean that
727          * there is no condition, and the next available sample shall
728          * get returned to the caller.
729          */
730         py_conds = Py_None;
731         if (!PyArg_ParseTuple(args, "|O", &py_conds)) {
732                 /* Let Python raise this exception. */
733                 goto err;
734         }
735         if (py_conds == Py_None) {
736                 /* 'py_conds' is None. */
737                 goto ret_9999;
738         } else if (PyList_Check(py_conds)) {
739                 /* 'py_conds' is a list. */
740                 py_conditionlist = py_conds;
741                 num_conditions = PyList_Size(py_conditionlist);
742                 if (num_conditions == 0)
743                         goto ret_9999; /* The PD invoked self.wait([]). */
744                 Py_IncRef(py_conditionlist);
745         } else if (PyDict_Check(py_conds)) {
746                 /* 'py_conds' is a dict. */
747                 if (PyDict_Size(py_conds) == 0)
748                         goto ret_9999; /* The PD invoked self.wait({}). */
749                 /* Make a list and put the dict in there for convenience. */
750                 py_conditionlist = PyList_New(1);
751                 Py_IncRef(py_conds);
752                 PyList_SetItem(py_conditionlist, 0, py_conds);
753                 num_conditions = 1;
754         } else {
755                 srd_err("Condition list is neither a list nor a dict.");
756                 goto err;
757         }
758
759         /* Free the old condition list. */
760         condition_list_free(di);
761
762         ret = SRD_OK;
763
764         /* Iterate over the conditions, set di->condition_list accordingly. */
765         for (i = 0; i < num_conditions; i++) {
766                 /* Get a condition (dict) from the condition list. */
767                 py_dict = PyList_GetItem(py_conditionlist, i);
768                 if (!PyDict_Check(py_dict)) {
769                         srd_err("Condition is not a dict.");
770                         ret = SRD_ERR;
771                         break;
772                 }
773
774                 /* Create the list of terms in this condition. */
775                 if ((ret = create_term_list(py_dict, &term_list)) < 0)
776                         break;
777
778                 /* Add the new condition to the PD instance's condition list. */
779                 di->condition_list = g_slist_append(di->condition_list, term_list);
780         }
781
782         Py_DecRef(py_conditionlist);
783
784         PyGILState_Release(gstate);
785
786         return ret;
787
788 err:
789         PyGILState_Release(gstate);
790
791         return SRD_ERR;
792
793 ret_9999:
794         PyGILState_Release(gstate);
795
796         return 9999;
797 }
798
799 /**
800  * Create a SKIP condition list for condition-less .wait() calls.
801  *
802  * @param di Decoder instance.
803  * @param count Number of samples to skip.
804  *
805  * @retval SRD_OK The new condition list was set successfully.
806  * @retval SRD_ERR There was an error setting the new condition list.
807  *                 The contents of di->condition_list are undefined.
808  *
809  * This routine is a reduced and specialized version of the @ref
810  * set_new_condition_list() and @ref create_term_list() routines which
811  * gets invoked when .wait() was called without specifications for
812  * conditions. This minor duplication of the SKIP term list creation
813  * simplifies the logic and avoids the creation of expensive Python
814  * objects with "constant" values which the caller did not pass in the
815  * first place. It results in maximum sharing of match handling code
816  * paths.
817  */
818 static int set_skip_condition(struct srd_decoder_inst *di, uint64_t count)
819 {
820         struct srd_term *term;
821         GSList *term_list;
822
823         condition_list_free(di);
824         term = g_malloc(sizeof(*term));
825         term->type = SRD_TERM_SKIP;
826         term->num_samples_to_skip = count;
827         term->num_samples_already_skipped = 0;
828         term_list = g_slist_append(NULL, term);
829         di->condition_list = g_slist_append(di->condition_list, term_list);
830
831         return SRD_OK;
832 }
833
834 static PyObject *Decoder_wait(PyObject *self, PyObject *args)
835 {
836         int ret;
837         uint64_t skip_count;
838         unsigned int i;
839         gboolean found_match;
840         struct srd_decoder_inst *di;
841         PyObject *py_pinvalues, *py_matched;
842         PyGILState_STATE gstate;
843
844         if (!self || !args)
845                 return NULL;
846
847         gstate = PyGILState_Ensure();
848
849         if (!(di = srd_inst_find_by_obj(NULL, self))) {
850                 PyErr_SetString(PyExc_Exception, "decoder instance not found");
851                 PyGILState_Release(gstate);
852                 Py_RETURN_NONE;
853         }
854
855         ret = set_new_condition_list(self, args);
856         if (ret < 0) {
857                 srd_dbg("%s: %s: Aborting wait().", di->inst_id, __func__);
858                 goto err;
859         }
860         if (ret == 9999) {
861                 /*
862                  * Empty condition list, automatic match. Arrange for the
863                  * execution of regular match handling code paths such that
864                  * the next available sample is returned to the caller.
865                  * Make sure to skip one sample when "anywhere within the
866                  * stream", yet make sure to not skip sample number 0.
867                  */
868                 if (di->abs_cur_samplenum)
869                         skip_count = 1;
870                 else if (!di->condition_list)
871                         skip_count = 0;
872                 else
873                         skip_count = 1;
874                 ret = set_skip_condition(di, skip_count);
875                 if (ret < 0) {
876                         srd_dbg("%s: %s: Cannot setup condition-less wait().",
877                                 di->inst_id, __func__);
878                         goto err;
879                 }
880         }
881
882         while (1) {
883
884                 Py_BEGIN_ALLOW_THREADS
885
886                 /* Wait for new samples to process, or termination request. */
887                 g_mutex_lock(&di->data_mutex);
888                 while (!di->got_new_samples && !di->want_wait_terminate)
889                         g_cond_wait(&di->got_new_samples_cond, &di->data_mutex);
890
891                 /*
892                  * Check whether any of the current condition(s) match.
893                  * Arrange for termination requests to take a code path which
894                  * won't find new samples to process, pretends to have processed
895                  * previously stored samples, and returns to the main thread,
896                  * while the termination request still gets signalled.
897                  */
898                 found_match = FALSE;
899
900                 /* Ignore return value for now, should never be negative. */
901                 (void)process_samples_until_condition_match(di, &found_match);
902
903                 Py_END_ALLOW_THREADS
904
905                 /* If there's a match, set self.samplenum etc. and return. */
906                 if (found_match) {
907                         /* Set self.samplenum to the (absolute) sample number that matched. */
908                         PyObject_SetAttrString(di->py_inst, "samplenum",
909                                 PyLong_FromLong(di->abs_cur_samplenum));
910
911                         if (di->match_array && di->match_array->len > 0) {
912                                 py_matched = PyTuple_New(di->match_array->len);
913                                 for (i = 0; i < di->match_array->len; i++)
914                                         PyTuple_SetItem(py_matched, i, PyBool_FromLong(di->match_array->data[i]));
915                                 PyObject_SetAttrString(di->py_inst, "matched", py_matched);
916                                 match_array_free(di);
917                         } else {
918                                 PyObject_SetAttrString(di->py_inst, "matched", Py_None);
919                         }
920
921                         py_pinvalues = get_current_pinvalues(di);
922
923                         g_mutex_unlock(&di->data_mutex);
924
925                         PyGILState_Release(gstate);
926
927                         return py_pinvalues;
928                 }
929
930                 /* No match, reset state for the next chunk. */
931                 di->got_new_samples = FALSE;
932                 di->handled_all_samples = TRUE;
933                 di->abs_start_samplenum = 0;
934                 di->abs_end_samplenum = 0;
935                 di->inbuf = NULL;
936                 di->inbuflen = 0;
937
938                 /* Signal the main thread that we handled all samples. */
939                 g_cond_signal(&di->handled_all_samples_cond);
940
941                 /*
942                  * When termination of wait() and decode() was requested,
943                  * then exit the loop after releasing the mutex.
944                  */
945                 if (di->want_wait_terminate) {
946                         srd_dbg("%s: %s: Will return from wait().",
947                                 di->inst_id, __func__);
948                         g_mutex_unlock(&di->data_mutex);
949                         goto err;
950                 }
951
952                 g_mutex_unlock(&di->data_mutex);
953         }
954
955         PyGILState_Release(gstate);
956
957         Py_RETURN_NONE;
958
959 err:
960         PyGILState_Release(gstate);
961
962         return NULL;
963 }
964
965 /**
966  * Return whether the specified channel was supplied to the decoder.
967  *
968  * @param self TODO. Must not be NULL.
969  * @param args TODO. Must not be NULL.
970  *
971  * @retval Py_True The channel has been supplied by the frontend.
972  * @retval Py_False The channel has been supplied by the frontend.
973  * @retval NULL An error occurred.
974  */
975 static PyObject *Decoder_has_channel(PyObject *self, PyObject *args)
976 {
977         int idx, count;
978         struct srd_decoder_inst *di;
979         PyGILState_STATE gstate;
980
981         if (!self || !args)
982                 return NULL;
983
984         gstate = PyGILState_Ensure();
985
986         if (!(di = srd_inst_find_by_obj(NULL, self))) {
987                 PyErr_SetString(PyExc_Exception, "decoder instance not found");
988                 goto err;
989         }
990
991         /*
992          * Get the integer argument of self.has_channel(). Check for
993          * the range of supported PD input channel numbers.
994          */
995         if (!PyArg_ParseTuple(args, "i", &idx)) {
996                 /* Let Python raise this exception. */
997                 goto err;
998         }
999
1000         count = g_slist_length(di->decoder->channels) +
1001                 g_slist_length(di->decoder->opt_channels);
1002         if (idx < 0 || idx >= count) {
1003                 srd_err("Invalid index %d, PD channel count %d.", idx, count);
1004                 PyErr_SetString(PyExc_IndexError, "invalid channel index");
1005                 goto err;
1006         }
1007
1008         PyGILState_Release(gstate);
1009
1010         return (di->dec_channelmap[idx] == -1) ? Py_False : Py_True;
1011
1012 err:
1013         PyGILState_Release(gstate);
1014
1015         return NULL;
1016 }
1017
1018 static PyMethodDef Decoder_methods[] = {
1019         { "put", Decoder_put, METH_VARARGS,
1020           "Accepts a dictionary with the following keys: startsample, endsample, data" },
1021         { "register", (PyCFunction)Decoder_register, METH_VARARGS|METH_KEYWORDS,
1022                         "Register a new output stream" },
1023         { "wait", Decoder_wait, METH_VARARGS,
1024                         "Wait for one or more conditions to occur" },
1025         { "has_channel", Decoder_has_channel, METH_VARARGS,
1026                         "Report whether a channel was supplied" },
1027         {NULL, NULL, 0, NULL}
1028 };
1029
1030 /**
1031  * Create the sigrokdecode.Decoder type.
1032  *
1033  * @return The new type object.
1034  *
1035  * @private
1036  */
1037 SRD_PRIV PyObject *srd_Decoder_type_new(void)
1038 {
1039         PyType_Spec spec;
1040         PyType_Slot slots[] = {
1041                 { Py_tp_doc, "sigrok Decoder base class" },
1042                 { Py_tp_methods, Decoder_methods },
1043                 { Py_tp_new, (void *)&PyType_GenericNew },
1044                 { 0, NULL }
1045         };
1046         PyObject *py_obj;
1047         PyGILState_STATE gstate;
1048
1049         gstate = PyGILState_Ensure();
1050
1051         spec.name = "sigrokdecode.Decoder";
1052         spec.basicsize = sizeof(srd_Decoder);
1053         spec.itemsize = 0;
1054         spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
1055         spec.slots = slots;
1056
1057         py_obj = PyType_FromSpec(&spec);
1058
1059         PyGILState_Release(gstate);
1060
1061         return py_obj;
1062 }