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