]> sigrok.org Git - libsigrokdecode.git/blame_incremental - type_decoder.c
uart: handle zero stop bits configuration
[libsigrokdecode.git] / type_decoder.c
... / ...
CommitLineData
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 */
26extern SRD_PRIV GSList *sessions;
27/** @endcond */
28
29typedef struct {
30 PyObject_HEAD
31} srd_Decoder;
32
33/* This is only used for nicer srd_dbg() output. */
34SRD_PRIV const char *output_type_name(unsigned int idx)
35{
36 static const char *names[] = {
37 "OUTPUT_ANN",
38 "OUTPUT_PYTHON",
39 "OUTPUT_BINARY",
40 "OUTPUT_LOGIC",
41 "OUTPUT_META",
42 "(invalid)"
43 };
44
45 return names[MIN(idx, G_N_ELEMENTS(names) - 1)];
46}
47
48static void release_annotation(struct srd_proto_data_annotation *pda)
49{
50 if (!pda)
51 return;
52 if (pda->ann_text)
53 g_strfreev(pda->ann_text);
54}
55
56static 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 = pdata->data;
114 pda->ann_class = ann_class;
115 pda->ann_text = ann_text;
116
117 PyGILState_Release(gstate);
118
119 return SRD_OK;
120
121err:
122 PyGILState_Release(gstate);
123
124 return SRD_ERR_PYTHON;
125}
126
127static void release_logic(struct srd_proto_data_logic *pdl)
128{
129 if (!pdl)
130 return;
131 g_free((void *)pdl->data);
132}
133
134static int convert_logic(struct srd_decoder_inst *di, PyObject *obj,
135 struct srd_proto_data *pdata)
136{
137 struct srd_proto_data_logic *pdl;
138 PyObject *py_tmp;
139 Py_ssize_t size;
140 int logic_group;
141 char *group_name, *buf;
142 PyGILState_STATE gstate;
143
144 gstate = PyGILState_Ensure();
145
146 /* Should be a list of [logic group, bytes]. */
147 if (!PyList_Check(obj)) {
148 srd_err("Protocol decoder %s submitted non-list for SRD_OUTPUT_LOGIC.",
149 di->decoder->name);
150 goto err;
151 }
152
153 /* Should have 2 elements. */
154 if (PyList_Size(obj) != 2) {
155 srd_err("Protocol decoder %s submitted SRD_OUTPUT_LOGIC list "
156 "with %zd elements instead of 2", di->decoder->name,
157 PyList_Size(obj));
158 goto err;
159 }
160
161 /* The first element should be an integer. */
162 py_tmp = PyList_GetItem(obj, 0);
163 if (!PyLong_Check(py_tmp)) {
164 srd_err("Protocol decoder %s submitted SRD_OUTPUT_LOGIC list, "
165 "but first element was not an integer.", di->decoder->name);
166 goto err;
167 }
168 logic_group = PyLong_AsLong(py_tmp);
169 if (!(group_name = g_slist_nth_data(di->decoder->logic_output_channels, logic_group))) {
170 srd_err("Protocol decoder %s submitted SRD_OUTPUT_LOGIC with "
171 "unregistered logic group %d.", di->decoder->name, logic_group);
172 goto err;
173 }
174
175 /* Second element should be bytes. */
176 py_tmp = PyList_GetItem(obj, 1);
177 if (!PyBytes_Check(py_tmp)) {
178 srd_err("Protocol decoder %s submitted SRD_OUTPUT_LOGIC list, "
179 "but second element was not bytes.", di->decoder->name);
180 goto err;
181 }
182
183 /* Consider an empty set of bytes a bug. */
184 if (PyBytes_Size(py_tmp) == 0) {
185 srd_err("Protocol decoder %s submitted SRD_OUTPUT_LOGIC "
186 "with empty data set.", di->decoder->name);
187 goto err;
188 }
189
190 if (PyBytes_AsStringAndSize(py_tmp, &buf, &size) == -1)
191 goto err;
192
193 PyGILState_Release(gstate);
194
195 pdl = pdata->data;
196 pdl->logic_group = logic_group;
197 /* pdl->repeat_count is set by the caller as it depends on the sample range */
198 if (!(pdl->data = g_try_malloc(size)))
199 return SRD_ERR_MALLOC;
200 memcpy((void *)pdl->data, (const void *)buf, size);
201
202 return SRD_OK;
203
204err:
205 PyGILState_Release(gstate);
206
207 return SRD_ERR_PYTHON;
208}
209
210static void release_binary(struct srd_proto_data_binary *pdb)
211{
212 if (!pdb)
213 return;
214 g_free((void *)pdb->data);
215}
216
217static int convert_binary(struct srd_decoder_inst *di, PyObject *obj,
218 struct srd_proto_data *pdata)
219{
220 struct srd_proto_data_binary *pdb;
221 PyObject *py_tmp;
222 Py_ssize_t size;
223 int bin_class;
224 char *class_name, *buf;
225 PyGILState_STATE gstate;
226
227 gstate = PyGILState_Ensure();
228
229 /* Should be a list of [binary class, bytes]. */
230 if (!PyList_Check(obj)) {
231 srd_err("Protocol decoder %s submitted non-list for SRD_OUTPUT_BINARY.",
232 di->decoder->name);
233 goto err;
234 }
235
236 /* Should have 2 elements. */
237 if (PyList_Size(obj) != 2) {
238 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list "
239 "with %zd elements instead of 2", di->decoder->name,
240 PyList_Size(obj));
241 goto err;
242 }
243
244 /* The first element should be an integer. */
245 py_tmp = PyList_GetItem(obj, 0);
246 if (!PyLong_Check(py_tmp)) {
247 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, "
248 "but first element was not an integer.", di->decoder->name);
249 goto err;
250 }
251 bin_class = PyLong_AsLong(py_tmp);
252 if (!(class_name = g_slist_nth_data(di->decoder->binary, bin_class))) {
253 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY with "
254 "unregistered binary class %d.", di->decoder->name, bin_class);
255 goto err;
256 }
257
258 /* Second element should be bytes. */
259 py_tmp = PyList_GetItem(obj, 1);
260 if (!PyBytes_Check(py_tmp)) {
261 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, "
262 "but second element was not bytes.", di->decoder->name);
263 goto err;
264 }
265
266 /* Consider an empty set of bytes a bug. */
267 if (PyBytes_Size(py_tmp) == 0) {
268 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY "
269 "with empty data set.", di->decoder->name);
270 goto err;
271 }
272
273 if (PyBytes_AsStringAndSize(py_tmp, &buf, &size) == -1)
274 goto err;
275
276 PyGILState_Release(gstate);
277
278 pdb = pdata->data;
279 pdb->bin_class = bin_class;
280 pdb->size = size;
281 if (!(pdb->data = g_try_malloc(pdb->size)))
282 return SRD_ERR_MALLOC;
283 memcpy((void *)pdb->data, (const void *)buf, pdb->size);
284
285 return SRD_OK;
286
287err:
288 PyGILState_Release(gstate);
289
290 return SRD_ERR_PYTHON;
291}
292
293static inline struct srd_decoder_inst *srd_sess_inst_find_by_obj(
294 struct srd_session *sess, const GSList *stack, const PyObject *obj)
295{
296 const GSList *l;
297 struct srd_decoder_inst *tmp, *di;
298
299 if (!sess)
300 return NULL;
301
302 di = NULL;
303 for (l = stack ? stack : sess->di_list; di == NULL && l != NULL; l = l->next) {
304 tmp = l->data;
305 if (tmp->py_inst == obj)
306 di = tmp;
307 else if (tmp->next_di)
308 di = srd_sess_inst_find_by_obj(sess, tmp->next_di, obj);
309 }
310
311 return di;
312}
313
314/**
315 * Find a decoder instance by its Python object.
316 *
317 * I.e. find that instance's instantiation of the sigrokdecode.Decoder class.
318 * This will recurse to find the instance anywhere in the stack tree of all
319 * sessions.
320 *
321 * @param stack Pointer to a GSList of struct srd_decoder_inst, indicating the
322 * stack to search. To start searching at the bottom level of
323 * decoder instances, pass NULL.
324 * @param obj The Python class instantiation.
325 *
326 * @return Pointer to struct srd_decoder_inst, or NULL if not found.
327 *
328 * @since 0.1.0
329 */
330static inline struct srd_decoder_inst *srd_inst_find_by_obj(
331 const GSList *stack, const PyObject *obj)
332{
333 struct srd_decoder_inst *di;
334 struct srd_session *sess;
335 GSList *l;
336
337 /* Performance shortcut: Handle the most common case first. */
338 sess = sessions->data;
339 di = sess->di_list->data;
340 if (di->py_inst == obj)
341 return di;
342
343 di = NULL;
344 for (l = sessions; di == NULL && l != NULL; l = l->next) {
345 sess = l->data;
346 di = srd_sess_inst_find_by_obj(sess, stack, obj);
347 }
348
349 return di;
350}
351
352static int convert_meta(struct srd_proto_data *pdata, PyObject *obj)
353{
354 long long intvalue;
355 double dvalue;
356 PyGILState_STATE gstate;
357
358 gstate = PyGILState_Ensure();
359
360 if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_INT64)) {
361 if (!PyLong_Check(obj)) {
362 PyErr_Format(PyExc_TypeError, "This output was registered "
363 "as 'int', but something else was passed.");
364 goto err;
365 }
366 intvalue = PyLong_AsLongLong(obj);
367 if (PyErr_Occurred())
368 goto err;
369 pdata->data = g_variant_new_int64(intvalue);
370 } else if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_DOUBLE)) {
371 if (!PyFloat_Check(obj)) {
372 PyErr_Format(PyExc_TypeError, "This output was registered "
373 "as 'float', but something else was passed.");
374 goto err;
375 }
376 dvalue = PyFloat_AsDouble(obj);
377 if (PyErr_Occurred())
378 goto err;
379 pdata->data = g_variant_new_double(dvalue);
380 }
381
382 PyGILState_Release(gstate);
383
384 return SRD_OK;
385
386err:
387 PyGILState_Release(gstate);
388
389 return SRD_ERR_PYTHON;
390}
391
392static void release_meta(GVariant *gvar)
393{
394 if (!gvar)
395 return;
396 g_variant_unref(gvar);
397}
398
399PyDoc_STRVAR(Decoder_put_doc,
400 "Put an annotation for the specified span of samples.\n"
401 "\n"
402 "Arguments: start and end sample number, stream id, annotation data.\n"
403 "Annotation data's layout depends on the output stream type."
404);
405
406static PyObject *Decoder_put(PyObject *self, PyObject *args)
407{
408 GSList *l;
409 PyObject *py_data, *py_res;
410 struct srd_decoder_inst *di, *next_di;
411 struct srd_pd_output *pdo;
412 struct srd_proto_data pdata;
413 struct srd_proto_data_annotation pda;
414 struct srd_proto_data_binary pdb;
415 struct srd_proto_data_logic pdl;
416 uint64_t start_sample, end_sample;
417 int output_id;
418 struct srd_pd_callback *cb;
419 PyGILState_STATE gstate;
420
421 py_data = NULL;
422
423 gstate = PyGILState_Ensure();
424
425 if (!(di = srd_inst_find_by_obj(NULL, self))) {
426 /* Shouldn't happen. */
427 srd_dbg("put(): self instance not found.");
428 goto err;
429 }
430
431 if (!PyArg_ParseTuple(args, "KKiO", &start_sample, &end_sample,
432 &output_id, &py_data)) {
433 /*
434 * This throws an exception, but by returning NULL here we let
435 * Python raise it. This results in a much better trace in
436 * controller.c on the decode() method call.
437 */
438 goto err;
439 }
440
441 if (!(l = g_slist_nth(di->pd_output, output_id))) {
442 srd_err("Protocol decoder %s submitted invalid output ID %d.",
443 di->decoder->name, output_id);
444 goto err;
445 }
446 pdo = l->data;
447
448 /* Upon SRD_OUTPUT_PYTHON for stacked PDs, we have a nicer log message later. */
449 if (pdo->output_type != SRD_OUTPUT_PYTHON && di->next_di != NULL) {
450 srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s on "
451 "oid %d (%s).", di->inst_id, start_sample, end_sample,
452 output_type_name(pdo->output_type), output_id,
453 pdo->proto_id);
454 }
455
456 pdata.start_sample = start_sample;
457 pdata.end_sample = end_sample;
458 pdata.pdo = pdo;
459 pdata.data = NULL;
460
461 switch (pdo->output_type) {
462 case SRD_OUTPUT_ANN:
463 /* Annotations are only fed to callbacks. */
464 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
465 pdata.data = &pda;
466 /* Convert from PyDict to srd_proto_data_annotation. */
467 if (convert_annotation(di, py_data, &pdata) != SRD_OK) {
468 /* An error was already logged. */
469 break;
470 }
471 Py_BEGIN_ALLOW_THREADS
472 cb->cb(&pdata, cb->cb_data);
473 Py_END_ALLOW_THREADS
474 release_annotation(pdata.data);
475 }
476 break;
477 case SRD_OUTPUT_PYTHON:
478 for (l = di->next_di; l; l = l->next) {
479 next_di = l->data;
480 srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s "
481 "on oid %d (%s) to instance %s.", di->inst_id,
482 start_sample,
483 end_sample, output_type_name(pdo->output_type),
484 output_id, pdo->proto_id, next_di->inst_id);
485 if (!(py_res = PyObject_CallMethod(
486 next_di->py_inst, "decode", "KKO", start_sample,
487 end_sample, py_data))) {
488 srd_exception_catch("Calling %s decode() failed",
489 next_di->inst_id);
490 }
491 Py_XDECREF(py_res);
492 }
493 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
494 /*
495 * Frontends aren't really supposed to get Python
496 * callbacks, but it's useful for testing.
497 */
498 pdata.data = py_data;
499 cb->cb(&pdata, cb->cb_data);
500 }
501 break;
502 case SRD_OUTPUT_BINARY:
503 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
504 pdata.data = &pdb;
505 /* Convert from PyDict to srd_proto_data_binary. */
506 if (convert_binary(di, py_data, &pdata) != SRD_OK) {
507 /* An error was already logged. */
508 break;
509 }
510 Py_BEGIN_ALLOW_THREADS
511 cb->cb(&pdata, cb->cb_data);
512 Py_END_ALLOW_THREADS
513 release_binary(pdata.data);
514 }
515 break;
516 case SRD_OUTPUT_LOGIC:
517 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
518 pdata.data = &pdl;
519 /* Convert from PyDict to srd_proto_data_logic. */
520 if (convert_logic(di, py_data, &pdata) != SRD_OK) {
521 /* An error was already logged. */
522 break;
523 }
524 if (end_sample <= start_sample) {
525 srd_err("Ignored SRD_OUTPUT_LOGIC with invalid sample range.");
526 break;
527 }
528 pdl.repeat_count = (end_sample - start_sample) - 1;
529 Py_BEGIN_ALLOW_THREADS
530 cb->cb(&pdata, cb->cb_data);
531 Py_END_ALLOW_THREADS
532 release_logic(pdata.data);
533 }
534 break;
535 case SRD_OUTPUT_META:
536 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
537 /* Annotations need converting from PyObject. */
538 if (convert_meta(&pdata, py_data) != SRD_OK) {
539 /* An exception was already set up. */
540 break;
541 }
542 Py_BEGIN_ALLOW_THREADS
543 cb->cb(&pdata, cb->cb_data);
544 Py_END_ALLOW_THREADS
545 release_meta(pdata.data);
546 }
547 break;
548 default:
549 srd_err("Protocol decoder %s submitted invalid output type %d.",
550 di->decoder->name, pdo->output_type);
551 break;
552 }
553
554 PyGILState_Release(gstate);
555
556 Py_RETURN_NONE;
557
558err:
559 PyGILState_Release(gstate);
560
561 return NULL;
562}
563
564PyDoc_STRVAR(Decoder_register_doc,
565 "Register a new output stream."
566);
567
568static PyObject *Decoder_register(PyObject *self,
569 PyObject *args, PyObject *kwargs)
570{
571 struct srd_decoder_inst *di;
572 struct srd_pd_output *pdo;
573 PyObject *py_new_output_id;
574 PyTypeObject *meta_type_py;
575 const GVariantType *meta_type_gv;
576 int output_type;
577 char *proto_id, *meta_name, *meta_descr;
578 char *keywords[] = { "output_type", "proto_id", "meta", NULL };
579 PyGILState_STATE gstate;
580 gboolean is_meta;
581 GSList *l;
582 struct srd_pd_output *cmp;
583
584 gstate = PyGILState_Ensure();
585
586 meta_type_py = NULL;
587 meta_type_gv = NULL;
588 meta_name = meta_descr = NULL;
589
590 if (!(di = srd_inst_find_by_obj(NULL, self))) {
591 PyErr_SetString(PyExc_Exception, "decoder instance not found");
592 goto err;
593 }
594
595 /* Default to instance ID, which defaults to class ID. */
596 proto_id = di->inst_id;
597 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|s(Oss)", keywords,
598 &output_type, &proto_id,
599 &meta_type_py, &meta_name, &meta_descr)) {
600 /* Let Python raise this exception. */
601 goto err;
602 }
603
604 /* Check if the meta value's type is supported. */
605 is_meta = output_type == SRD_OUTPUT_META;
606 if (is_meta) {
607 if (meta_type_py == &PyLong_Type)
608 meta_type_gv = G_VARIANT_TYPE_INT64;
609 else if (meta_type_py == &PyFloat_Type)
610 meta_type_gv = G_VARIANT_TYPE_DOUBLE;
611 else {
612 PyErr_Format(PyExc_TypeError, "Unsupported type.");
613 goto err;
614 }
615 }
616
617 pdo = NULL;
618 for (l = di->pd_output; l; l = l->next) {
619 cmp = l->data;
620 if (cmp->output_type != output_type)
621 continue;
622 if (strcmp(cmp->proto_id, proto_id) != 0)
623 continue;
624 if (is_meta && cmp->meta_type != meta_type_gv)
625 continue;
626 if (is_meta && strcmp(cmp->meta_name, meta_name) != 0)
627 continue;
628 if (is_meta && strcmp(cmp->meta_descr, meta_descr) != 0)
629 continue;
630 pdo = cmp;
631 break;
632 }
633 if (pdo) {
634 py_new_output_id = Py_BuildValue("i", pdo->pdo_id);
635 PyGILState_Release(gstate);
636 return py_new_output_id;
637 }
638
639 pdo = g_malloc(sizeof(struct srd_pd_output));
640
641 /* pdo_id is just a simple index, nothing is deleted from this list anyway. */
642 pdo->pdo_id = g_slist_length(di->pd_output);
643 pdo->output_type = output_type;
644 pdo->di = di;
645 pdo->proto_id = g_strdup(proto_id);
646
647 if (output_type == SRD_OUTPUT_META) {
648 pdo->meta_type = meta_type_gv;
649 pdo->meta_name = g_strdup(meta_name);
650 pdo->meta_descr = g_strdup(meta_descr);
651 }
652
653 di->pd_output = g_slist_append(di->pd_output, pdo);
654 py_new_output_id = Py_BuildValue("i", pdo->pdo_id);
655
656 PyGILState_Release(gstate);
657
658 srd_dbg("Instance %s creating new output type %s as oid %d (%s).",
659 di->inst_id, output_type_name(output_type), pdo->pdo_id,
660 proto_id);
661
662 return py_new_output_id;
663
664err:
665 PyGILState_Release(gstate);
666
667 return NULL;
668}
669
670static int get_term_type(const char *v)
671{
672 switch (v[0]) {
673 case 'h':
674 return SRD_TERM_HIGH;
675 case 'l':
676 return SRD_TERM_LOW;
677 case 'r':
678 return SRD_TERM_RISING_EDGE;
679 case 'f':
680 return SRD_TERM_FALLING_EDGE;
681 case 'e':
682 return SRD_TERM_EITHER_EDGE;
683 case 'n':
684 return SRD_TERM_NO_EDGE;
685 default:
686 return -1;
687 }
688
689 return -1;
690}
691
692/**
693 * Get the pin values at the current sample number.
694 *
695 * @param di The decoder instance to use. Must not be NULL.
696 * The number of channels must be >= 1.
697 *
698 * @return A newly allocated PyTuple containing the pin values at the
699 * current sample number.
700 */
701static PyObject *get_current_pinvalues(const struct srd_decoder_inst *di)
702{
703 int i;
704 uint8_t sample;
705 const uint8_t *sample_pos;
706 int byte_offset, bit_offset;
707 PyObject *py_pinvalues;
708 PyGILState_STATE gstate;
709
710 if (!di) {
711 srd_err("Invalid decoder instance.");
712 return NULL;
713 }
714
715 gstate = PyGILState_Ensure();
716
717 py_pinvalues = PyTuple_New(di->dec_num_channels);
718
719 for (i = 0; i < di->dec_num_channels; i++) {
720 /* A channelmap value of -1 means "unused optional channel". */
721 if (di->dec_channelmap[i] == -1) {
722 /* Value of unused channel is 0xff, instead of 0 or 1. */
723 PyTuple_SetItem(py_pinvalues, i, PyLong_FromUnsignedLong(0xff));
724 } else {
725 sample_pos = di->inbuf + ((di->abs_cur_samplenum - di->abs_start_samplenum) * di->data_unitsize);
726 byte_offset = di->dec_channelmap[i] / 8;
727 bit_offset = di->dec_channelmap[i] % 8;
728 sample = *(sample_pos + byte_offset) & (1 << bit_offset) ? 1 : 0;
729 PyTuple_SetItem(py_pinvalues, i, PyLong_FromUnsignedLong(sample));
730 }
731 }
732
733 PyGILState_Release(gstate);
734
735 return py_pinvalues;
736}
737
738/**
739 * Create a list of terms in the specified condition.
740 *
741 * If there are no terms in the condition, 'term_list' will be NULL.
742 *
743 * @param di The decoder instance to use. Must not be NULL.
744 * @param py_dict A Python dict containing terms. Must not be NULL.
745 * @param term_list Pointer to a GSList which will be set to the newly
746 * created list of terms. Must not be NULL.
747 *
748 * @return SRD_OK upon success, a negative error code otherwise.
749 */
750static int create_term_list(struct srd_decoder_inst *di,
751 PyObject *py_dict, GSList **term_list)
752{
753 Py_ssize_t pos = 0;
754 PyObject *py_key, *py_value;
755 struct srd_term *term;
756 int64_t num_samples_to_skip;
757 char *term_str;
758 PyGILState_STATE gstate;
759
760 if (!py_dict || !term_list)
761 return SRD_ERR_ARG;
762
763 /* "Create" an empty GSList of terms. */
764 *term_list = NULL;
765
766 gstate = PyGILState_Ensure();
767
768 /* Iterate over all items in the current dict. */
769 while (PyDict_Next(py_dict, &pos, &py_key, &py_value)) {
770 /* Check whether the current key is a string or a number. */
771 if (PyLong_Check(py_key)) {
772 /* The key is a number. */
773 /* Get the value string. */
774 if ((py_pydictitem_as_str(py_dict, py_key, &term_str)) != SRD_OK) {
775 srd_err("Failed to get the value.");
776 goto err;
777 }
778 term = g_malloc(sizeof(struct srd_term));
779 term->type = get_term_type(term_str);
780 term->channel = PyLong_AsLong(py_key);
781 if (term->channel < 0 || term->channel >= di->dec_num_channels)
782 term->type = SRD_TERM_ALWAYS_FALSE;
783 g_free(term_str);
784 } else if (PyUnicode_Check(py_key)) {
785 /* The key is a string. */
786 /* TODO: Check if the key is "skip". */
787 if ((py_pydictitem_as_long(py_dict, py_key, &num_samples_to_skip)) != SRD_OK) {
788 srd_err("Failed to get number of samples to skip.");
789 goto err;
790 }
791 term = g_malloc(sizeof(struct srd_term));
792 term->type = SRD_TERM_SKIP;
793 term->num_samples_to_skip = num_samples_to_skip;
794 term->num_samples_already_skipped = 0;
795 if (num_samples_to_skip < 0)
796 term->type = SRD_TERM_ALWAYS_FALSE;
797 } else {
798 srd_err("Term key is neither a string nor a number.");
799 goto err;
800 }
801
802 /* Add the term to the list of terms. */
803 *term_list = g_slist_append(*term_list, term);
804 }
805
806 PyGILState_Release(gstate);
807
808 return SRD_OK;
809
810err:
811 PyGILState_Release(gstate);
812
813 return SRD_ERR;
814}
815
816/**
817 * Replace the current condition list with the new one.
818 *
819 * @param self TODO. Must not be NULL.
820 * @param args TODO. Must not be NULL.
821 *
822 * @retval SRD_OK The new condition list was set successfully.
823 * @retval SRD_ERR There was an error setting the new condition list.
824 * The contents of di->condition_list are undefined.
825 * @retval 9999 TODO.
826 */
827static int set_new_condition_list(PyObject *self, PyObject *args)
828{
829 struct srd_decoder_inst *di;
830 GSList *term_list;
831 PyObject *py_conditionlist, *py_conds, *py_dict;
832 int i, num_conditions, ret;
833 PyGILState_STATE gstate;
834
835 if (!self || !args)
836 return SRD_ERR_ARG;
837
838 gstate = PyGILState_Ensure();
839
840 /* Get the decoder instance. */
841 if (!(di = srd_inst_find_by_obj(NULL, self))) {
842 PyErr_SetString(PyExc_Exception, "decoder instance not found");
843 goto err;
844 }
845
846 /*
847 * Return an error condition from .wait() when termination is
848 * requested, such that decode() will terminate.
849 */
850 if (di->want_wait_terminate) {
851 srd_dbg("%s: %s: Skip (want_term).", di->inst_id, __func__);
852 goto err;
853 }
854
855 /*
856 * Parse the argument of self.wait() into 'py_conds', and check
857 * the data type. The argument is optional, None is assumed in
858 * its absence. None or an empty dict or an empty list mean that
859 * there is no condition, and the next available sample shall
860 * get returned to the caller.
861 */
862 py_conds = Py_None;
863 if (!PyArg_ParseTuple(args, "|O", &py_conds)) {
864 /* Let Python raise this exception. */
865 goto err;
866 }
867 if (py_conds == Py_None) {
868 /* 'py_conds' is None. */
869 goto ret_9999;
870 } else if (PyList_Check(py_conds)) {
871 /* 'py_conds' is a list. */
872 py_conditionlist = py_conds;
873 num_conditions = PyList_Size(py_conditionlist);
874 if (num_conditions == 0)
875 goto ret_9999; /* The PD invoked self.wait([]). */
876 Py_INCREF(py_conditionlist);
877 } else if (PyDict_Check(py_conds)) {
878 /* 'py_conds' is a dict. */
879 if (PyDict_Size(py_conds) == 0)
880 goto ret_9999; /* The PD invoked self.wait({}). */
881 /* Make a list and put the dict in there for convenience. */
882 py_conditionlist = PyList_New(1);
883 Py_INCREF(py_conds);
884 PyList_SetItem(py_conditionlist, 0, py_conds);
885 num_conditions = 1;
886 } else {
887 srd_err("Condition list is neither a list nor a dict.");
888 goto err;
889 }
890
891 /* Free the old condition list. */
892 condition_list_free(di);
893
894 ret = SRD_OK;
895
896 /* Iterate over the conditions, set di->condition_list accordingly. */
897 for (i = 0; i < num_conditions; i++) {
898 /* Get a condition (dict) from the condition list. */
899 py_dict = PyList_GetItem(py_conditionlist, i);
900 if (!PyDict_Check(py_dict)) {
901 srd_err("Condition is not a dict.");
902 ret = SRD_ERR;
903 break;
904 }
905
906 /* Create the list of terms in this condition. */
907 if ((ret = create_term_list(di, py_dict, &term_list)) < 0)
908 break;
909
910 /* Add the new condition to the PD instance's condition list. */
911 di->condition_list = g_slist_append(di->condition_list, term_list);
912 }
913
914 Py_DecRef(py_conditionlist);
915
916 PyGILState_Release(gstate);
917
918 return ret;
919
920err:
921 PyGILState_Release(gstate);
922
923 return SRD_ERR;
924
925ret_9999:
926 PyGILState_Release(gstate);
927
928 return 9999;
929}
930
931/**
932 * Create a SKIP condition list for condition-less .wait() calls.
933 *
934 * @param di Decoder instance.
935 * @param count Number of samples to skip.
936 *
937 * @retval SRD_OK The new condition list was set successfully.
938 * @retval SRD_ERR There was an error setting the new condition list.
939 * The contents of di->condition_list are undefined.
940 *
941 * This routine is a reduced and specialized version of the @ref
942 * set_new_condition_list() and @ref create_term_list() routines which
943 * gets invoked when .wait() was called without specifications for
944 * conditions. This minor duplication of the SKIP term list creation
945 * simplifies the logic and avoids the creation of expensive Python
946 * objects with "constant" values which the caller did not pass in the
947 * first place. It results in maximum sharing of match handling code
948 * paths.
949 */
950static int set_skip_condition(struct srd_decoder_inst *di, uint64_t count)
951{
952 struct srd_term *term;
953 GSList *term_list;
954
955 condition_list_free(di);
956 term = g_malloc(sizeof(*term));
957 term->type = SRD_TERM_SKIP;
958 term->num_samples_to_skip = count;
959 term->num_samples_already_skipped = 0;
960 term_list = g_slist_append(NULL, term);
961 di->condition_list = g_slist_append(di->condition_list, term_list);
962
963 return SRD_OK;
964}
965
966PyDoc_STRVAR(Decoder_wait_doc,
967 "Wait for one or more conditions to occur.\n"
968 "\n"
969 "Returns the sample data at the next position where the condition\n"
970 "is seen. When the optional condition is missing or empty, the next\n"
971 "sample number is used. The condition can be a dictionary with one\n"
972 "condition's details, or a list of dictionaries specifying multiple\n"
973 "conditions of which at least one condition must be true. Dicts can\n"
974 "contain one or more key/value pairs, all of which must be true for\n"
975 "the dict's condition to be considered true. The key either is a\n"
976 "channel index or a keyword, the value is the operation's parameter.\n"
977 "\n"
978 "Supported parameters for channel number keys: 'h', 'l', 'r', 'f',\n"
979 "or 'e' for level or edge conditions. Other supported keywords:\n"
980 "'skip' to advance over the given number of samples.\n"
981);
982
983static PyObject *Decoder_wait(PyObject *self, PyObject *args)
984{
985 int ret;
986 uint64_t skip_count;
987 unsigned int i;
988 gboolean found_match;
989 struct srd_decoder_inst *di;
990 PyObject *py_pinvalues, *py_matched, *py_samplenum;
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 PyGILState_Release(gstate);
1001 Py_RETURN_NONE;
1002 }
1003
1004 ret = set_new_condition_list(self, args);
1005 if (ret < 0) {
1006 srd_dbg("%s: %s: Aborting wait().", di->inst_id, __func__);
1007 goto err;
1008 }
1009 if (ret == 9999) {
1010 /*
1011 * Empty condition list, automatic match. Arrange for the
1012 * execution of regular match handling code paths such that
1013 * the next available sample is returned to the caller.
1014 * Make sure to skip one sample when "anywhere within the
1015 * stream", yet make sure to not skip sample number 0.
1016 */
1017 if (di->abs_cur_samplenum)
1018 skip_count = 1;
1019 else if (!di->condition_list)
1020 skip_count = 0;
1021 else
1022 skip_count = 1;
1023 ret = set_skip_condition(di, skip_count);
1024 if (ret < 0) {
1025 srd_dbg("%s: %s: Cannot setup condition-less wait().",
1026 di->inst_id, __func__);
1027 goto err;
1028 }
1029 }
1030
1031 while (1) {
1032
1033 Py_BEGIN_ALLOW_THREADS
1034
1035 /* Wait for new samples to process, or termination request. */
1036 g_mutex_lock(&di->data_mutex);
1037 while (!di->got_new_samples && !di->want_wait_terminate)
1038 g_cond_wait(&di->got_new_samples_cond, &di->data_mutex);
1039
1040 /*
1041 * Check whether any of the current condition(s) match.
1042 * Arrange for termination requests to take a code path which
1043 * won't find new samples to process, pretends to have processed
1044 * previously stored samples, and returns to the main thread,
1045 * while the termination request still gets signalled.
1046 */
1047 found_match = FALSE;
1048
1049 /* Ignore return value for now, should never be negative. */
1050 (void)process_samples_until_condition_match(di, &found_match);
1051
1052 Py_END_ALLOW_THREADS
1053
1054 /* If there's a match, set self.samplenum etc. and return. */
1055 if (found_match) {
1056 /* Set self.samplenum to the (absolute) sample number that matched. */
1057 py_samplenum = PyLong_FromUnsignedLongLong(di->abs_cur_samplenum);
1058 PyObject_SetAttrString(di->py_inst, "samplenum", py_samplenum);
1059 Py_DECREF(py_samplenum);
1060
1061 if (di->match_array && di->match_array->len > 0) {
1062 py_matched = PyTuple_New(di->match_array->len);
1063 for (i = 0; i < di->match_array->len; i++)
1064 PyTuple_SetItem(py_matched, i, PyBool_FromLong(di->match_array->data[i]));
1065 PyObject_SetAttrString(di->py_inst, "matched", py_matched);
1066 Py_DECREF(py_matched);
1067 match_array_free(di);
1068 } else {
1069 PyObject_SetAttrString(di->py_inst, "matched", Py_None);
1070 }
1071
1072 py_pinvalues = get_current_pinvalues(di);
1073
1074 g_mutex_unlock(&di->data_mutex);
1075
1076 PyGILState_Release(gstate);
1077
1078 return py_pinvalues;
1079 }
1080
1081 /* No match, reset state for the next chunk. */
1082 di->got_new_samples = FALSE;
1083 di->handled_all_samples = TRUE;
1084 di->abs_start_samplenum = 0;
1085 di->abs_end_samplenum = 0;
1086 di->inbuf = NULL;
1087 di->inbuflen = 0;
1088
1089 /* Signal the main thread that we handled all samples. */
1090 g_cond_signal(&di->handled_all_samples_cond);
1091
1092 /*
1093 * When EOF was provided externally, communicate the
1094 * Python EOFError exception to .decode() and return
1095 * from the .wait() method call. This is motivated by
1096 * the use of Python context managers, so that .decode()
1097 * methods can "close" incompletely accumulated data
1098 * when the sample data is exhausted.
1099 */
1100 if (di->communicate_eof) {
1101 srd_dbg("%s: %s: Raising EOF from wait().",
1102 di->inst_id, __func__);
1103 g_mutex_unlock(&di->data_mutex);
1104 PyErr_SetString(PyExc_EOFError, "samples exhausted");
1105 goto err;
1106 }
1107
1108 /*
1109 * When termination of wait() and decode() was requested,
1110 * then exit the loop after releasing the mutex.
1111 */
1112 if (di->want_wait_terminate) {
1113 srd_dbg("%s: %s: Will return from wait().",
1114 di->inst_id, __func__);
1115 g_mutex_unlock(&di->data_mutex);
1116 goto err;
1117 }
1118
1119 g_mutex_unlock(&di->data_mutex);
1120 }
1121
1122 PyGILState_Release(gstate);
1123
1124 Py_RETURN_NONE;
1125
1126err:
1127 PyGILState_Release(gstate);
1128
1129 return NULL;
1130}
1131
1132PyDoc_STRVAR(Decoder_has_channel_doc,
1133 "Check whether input data is supplied for a given channel.\n"
1134 "\n"
1135 "Argument: A channel index.\n"
1136 "Returns: A boolean, True if the channel is connected,\n"
1137 "False if the channel is open (won't see any input data).\n"
1138);
1139
1140/**
1141 * Return whether the specified channel was supplied to the decoder.
1142 *
1143 * @param self TODO. Must not be NULL.
1144 * @param args TODO. Must not be NULL.
1145 *
1146 * @retval Py_True The channel has been supplied by the frontend.
1147 * @retval Py_False The channel has been supplied by the frontend.
1148 * @retval NULL An error occurred.
1149 */
1150static PyObject *Decoder_has_channel(PyObject *self, PyObject *args)
1151{
1152 int idx, count;
1153 struct srd_decoder_inst *di;
1154 PyGILState_STATE gstate;
1155 PyObject *bool_ret;
1156
1157 if (!self || !args)
1158 return NULL;
1159
1160 gstate = PyGILState_Ensure();
1161
1162 if (!(di = srd_inst_find_by_obj(NULL, self))) {
1163 PyErr_SetString(PyExc_Exception, "decoder instance not found");
1164 goto err;
1165 }
1166
1167 /*
1168 * Get the integer argument of self.has_channel(). Check for
1169 * the range of supported PD input channel numbers.
1170 */
1171 if (!PyArg_ParseTuple(args, "i", &idx)) {
1172 /* Let Python raise this exception. */
1173 goto err;
1174 }
1175
1176 count = g_slist_length(di->decoder->channels) +
1177 g_slist_length(di->decoder->opt_channels);
1178 if (idx < 0 || idx >= count) {
1179 srd_err("Invalid index %d, PD channel count %d.", idx, count);
1180 PyErr_SetString(PyExc_IndexError, "invalid channel index");
1181 goto err;
1182 }
1183
1184 PyGILState_Release(gstate);
1185
1186 bool_ret = (di->dec_channelmap[idx] == -1) ? Py_False : Py_True;
1187 Py_INCREF(bool_ret);
1188 return bool_ret;
1189
1190err:
1191 PyGILState_Release(gstate);
1192
1193 return NULL;
1194}
1195
1196PyDoc_STRVAR(Decoder_doc, "sigrok Decoder base class");
1197
1198static PyMethodDef Decoder_methods[] = {
1199 { "put",
1200 Decoder_put, METH_VARARGS,
1201 Decoder_put_doc,
1202 },
1203 { "register",
1204 (PyCFunction)(void(*)(void))Decoder_register, METH_VARARGS | METH_KEYWORDS,
1205 Decoder_register_doc,
1206 },
1207 { "wait",
1208 Decoder_wait, METH_VARARGS,
1209 Decoder_wait_doc,
1210 },
1211 { "has_channel",
1212 Decoder_has_channel, METH_VARARGS,
1213 Decoder_has_channel_doc,
1214 },
1215 ALL_ZERO,
1216};
1217
1218/**
1219 * Create the sigrokdecode.Decoder type.
1220 *
1221 * @return The new type object.
1222 *
1223 * @private
1224 */
1225SRD_PRIV PyObject *srd_Decoder_type_new(void)
1226{
1227 PyType_Spec spec;
1228 PyType_Slot slots[] = {
1229 { Py_tp_doc, Decoder_doc },
1230 { Py_tp_methods, Decoder_methods },
1231 { Py_tp_new, (void *)&PyType_GenericNew },
1232 ALL_ZERO,
1233 };
1234 PyObject *py_obj;
1235 PyGILState_STATE gstate;
1236
1237 gstate = PyGILState_Ensure();
1238
1239 spec.name = "sigrokdecode.Decoder";
1240 spec.basicsize = sizeof(srd_Decoder);
1241 spec.itemsize = 0;
1242 spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
1243 spec.slots = slots;
1244
1245 py_obj = PyType_FromSpec(&spec);
1246
1247 PyGILState_Release(gstate);
1248
1249 return py_obj;
1250}