]> sigrok.org Git - libsigrokdecode.git/blame - type_decoder.c
uart: handle zero stop bits configuration
[libsigrokdecode.git] / type_decoder.c
CommitLineData
d0a0ed03 1/*
50bd5d25 2 * This file is part of the libsigrokdecode project.
d0a0ed03
BV
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
36784362 20#include <config.h>
f6c7eade
MC
21#include "libsigrokdecode-internal.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
22#include "libsigrokdecode.h"
dbeaab27 23#include <inttypes.h>
d0a0ed03 24
a4e9ca6f
UH
25/** @cond PRIVATE */
26extern SRD_PRIV GSList *sessions;
27/** @endcond */
28
17475b09
UH
29typedef struct {
30 PyObject_HEAD
31} srd_Decoder;
32
7969d803 33/* This is only used for nicer srd_dbg() output. */
5c723a57 34SRD_PRIV const char *output_type_name(unsigned int idx)
201a85a8 35{
487890c8 36 static const char *names[] = {
201a85a8
DE
37 "OUTPUT_ANN",
38 "OUTPUT_PYTHON",
39 "OUTPUT_BINARY",
ddcde186 40 "OUTPUT_LOGIC",
201a85a8
DE
41 "OUTPUT_META",
42 "(invalid)"
43 };
7969d803 44
201a85a8
DE
45 return names[MIN(idx, G_N_ELEMENTS(names) - 1)];
46}
58572aed 47
c1b2bbc1
GS
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);
c1b2bbc1
GS
54}
55
4f75f1c1 56static int convert_annotation(struct srd_decoder_inst *di, PyObject *obj,
0b922460 57 struct srd_proto_data *pdata)
d0a0ed03
BV
58{
59 PyObject *py_tmp;
60 struct srd_pd_output *pdo;
0b922460 61 struct srd_proto_data_annotation *pda;
280d554c 62 int ann_class;
0b922460 63 char **ann_text;
514b2edc
UH
64 PyGILState_STATE gstate;
65
66 gstate = PyGILState_Ensure();
d0a0ed03 67
280d554c 68 /* Should be a list of [annotation class, [string, ...]]. */
0679f5bf 69 if (!PyList_Check(obj)) {
201a85a8 70 srd_err("Protocol decoder %s submitted an annotation that"
0679f5bf 71 " is not a list", di->decoder->name);
514b2edc 72 goto err;
d0a0ed03
BV
73 }
74
361fdcaa 75 /* Should have 2 elements. */
d0a0ed03 76 if (PyList_Size(obj) != 2) {
c9bfccc6 77 srd_err("Protocol decoder %s submitted annotation list with "
4916b173 78 "%zd elements instead of 2", di->decoder->name,
c9bfccc6 79 PyList_Size(obj));
514b2edc 80 goto err;
d0a0ed03
BV
81 }
82
c9bfccc6
UH
83 /*
84 * The first element should be an integer matching a previously
280d554c 85 * registered annotation class.
c9bfccc6 86 */
d0a0ed03
BV
87 py_tmp = PyList_GetItem(obj, 0);
88 if (!PyLong_Check(py_tmp)) {
c9bfccc6
UH
89 srd_err("Protocol decoder %s submitted annotation list, but "
90 "first element was not an integer.", di->decoder->name);
514b2edc 91 goto err;
d0a0ed03 92 }
280d554c
UH
93 ann_class = PyLong_AsLong(py_tmp);
94 if (!(pdo = g_slist_nth_data(di->decoder->annotations, ann_class))) {
d906d3f9 95 srd_err("Protocol decoder %s submitted data to unregistered "
280d554c 96 "annotation class %d.", di->decoder->name, ann_class);
514b2edc 97 goto err;
d0a0ed03 98 }
d0a0ed03 99
361fdcaa 100 /* Second element must be a list. */
d0a0ed03
BV
101 py_tmp = PyList_GetItem(obj, 1);
102 if (!PyList_Check(py_tmp)) {
d906d3f9 103 srd_err("Protocol decoder %s submitted annotation list, but "
c9bfccc6 104 "second element was not a list.", di->decoder->name);
514b2edc 105 goto err;
d0a0ed03 106 }
62a2b15c 107 if (py_strseq_to_char(py_tmp, &ann_text) != SRD_OK) {
d906d3f9 108 srd_err("Protocol decoder %s submitted annotation list, but "
c9bfccc6 109 "second element was malformed.", di->decoder->name);
514b2edc 110 goto err;
d0a0ed03
BV
111 }
112
ee63c5dd 113 pda = pdata->data;
280d554c 114 pda->ann_class = ann_class;
0b922460 115 pda->ann_text = ann_text;
0b922460 116
514b2edc
UH
117 PyGILState_Release(gstate);
118
d0a0ed03 119 return SRD_OK;
514b2edc
UH
120
121err:
122 PyGILState_Release(gstate);
123
124 return SRD_ERR_PYTHON;
d0a0ed03
BV
125}
126
ddcde186
UH
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;
b8c8dc8a
SA
140 int logic_group;
141 char *group_name, *buf;
ddcde186
UH
142 PyGILState_STATE gstate;
143
144 gstate = PyGILState_Ensure();
145
b8c8dc8a 146 /* Should be a list of [logic group, bytes]. */
ddcde186
UH
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 }
b8c8dc8a
SA
168 logic_group = PyLong_AsLong(py_tmp);
169 if (!(group_name = g_slist_nth_data(di->decoder->logic_output_channels, logic_group))) {
ddcde186 170 srd_err("Protocol decoder %s submitted SRD_OUTPUT_LOGIC with "
b8c8dc8a 171 "unregistered logic group %d.", di->decoder->name, logic_group);
ddcde186
UH
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;
b8c8dc8a
SA
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)))
ddcde186 199 return SRD_ERR_MALLOC;
b8c8dc8a 200 memcpy((void *)pdl->data, (const void *)buf, size);
ddcde186
UH
201
202 return SRD_OK;
203
204err:
205 PyGILState_Release(gstate);
206
207 return SRD_ERR_PYTHON;
208}
209
c1b2bbc1
GS
210static void release_binary(struct srd_proto_data_binary *pdb)
211{
212 if (!pdb)
213 return;
8390f85a 214 g_free((void *)pdb->data);
c1b2bbc1
GS
215}
216
d75d8a7c
BV
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;
514b2edc
UH
225 PyGILState_STATE gstate;
226
227 gstate = PyGILState_Ensure();
d75d8a7c 228
2824e811
UH
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.",
201a85a8 232 di->decoder->name);
514b2edc 233 goto err;
d75d8a7c
BV
234 }
235
236 /* Should have 2 elements. */
2824e811
UH
237 if (PyList_Size(obj) != 2) {
238 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list "
4916b173 239 "with %zd elements instead of 2", di->decoder->name,
d75d8a7c 240 PyList_Size(obj));
514b2edc 241 goto err;
d75d8a7c
BV
242 }
243
244 /* The first element should be an integer. */
2824e811 245 py_tmp = PyList_GetItem(obj, 0);
d75d8a7c 246 if (!PyLong_Check(py_tmp)) {
2824e811 247 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, "
d75d8a7c 248 "but first element was not an integer.", di->decoder->name);
514b2edc 249 goto err;
d75d8a7c
BV
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);
514b2edc 255 goto err;
d75d8a7c
BV
256 }
257
258 /* Second element should be bytes. */
2824e811 259 py_tmp = PyList_GetItem(obj, 1);
d75d8a7c 260 if (!PyBytes_Check(py_tmp)) {
2824e811 261 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, "
d75d8a7c 262 "but second element was not bytes.", di->decoder->name);
514b2edc 263 goto err;
d75d8a7c
BV
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);
514b2edc 270 goto err;
d75d8a7c
BV
271 }
272
d75d8a7c 273 if (PyBytes_AsStringAndSize(py_tmp, &buf, &size) == -1)
514b2edc
UH
274 goto err;
275
276 PyGILState_Release(gstate);
277
c94631f1 278 pdb = pdata->data;
d75d8a7c
BV
279 pdb->bin_class = bin_class;
280 pdb->size = size;
c94631f1 281 if (!(pdb->data = g_try_malloc(pdb->size)))
d75d8a7c
BV
282 return SRD_ERR_MALLOC;
283 memcpy((void *)pdb->data, (const void *)buf, pdb->size);
d75d8a7c
BV
284
285 return SRD_OK;
514b2edc
UH
286
287err:
288 PyGILState_Release(gstate);
289
290 return SRD_ERR_PYTHON;
d75d8a7c
BV
291}
292
29adc171 293static inline struct srd_decoder_inst *srd_sess_inst_find_by_obj(
a4e9ca6f
UH
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 */
29adc171 330static inline struct srd_decoder_inst *srd_inst_find_by_obj(
a4e9ca6f
UH
331 const GSList *stack, const PyObject *obj)
332{
333 struct srd_decoder_inst *di;
334 struct srd_session *sess;
335 GSList *l;
336
996b17db
UH
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)
4f0d192d 341 return di;
996b17db 342
a4e9ca6f
UH
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
7ee0c40b
BV
352static int convert_meta(struct srd_proto_data *pdata, PyObject *obj)
353{
354 long long intvalue;
355 double dvalue;
514b2edc
UH
356 PyGILState_STATE gstate;
357
358 gstate = PyGILState_Ensure();
7ee0c40b 359
ec31b982 360 if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_INT64)) {
7ee0c40b
BV
361 if (!PyLong_Check(obj)) {
362 PyErr_Format(PyExc_TypeError, "This output was registered "
201a85a8 363 "as 'int', but something else was passed.");
514b2edc 364 goto err;
7ee0c40b
BV
365 }
366 intvalue = PyLong_AsLongLong(obj);
367 if (PyErr_Occurred())
514b2edc 368 goto err;
7ee0c40b 369 pdata->data = g_variant_new_int64(intvalue);
ec31b982 370 } else if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_DOUBLE)) {
7ee0c40b
BV
371 if (!PyFloat_Check(obj)) {
372 PyErr_Format(PyExc_TypeError, "This output was registered "
201a85a8 373 "as 'float', but something else was passed.");
514b2edc 374 goto err;
7ee0c40b
BV
375 }
376 dvalue = PyFloat_AsDouble(obj);
377 if (PyErr_Occurred())
514b2edc 378 goto err;
7ee0c40b
BV
379 pdata->data = g_variant_new_double(dvalue);
380 }
381
514b2edc
UH
382 PyGILState_Release(gstate);
383
7ee0c40b 384 return SRD_OK;
514b2edc
UH
385
386err:
387 PyGILState_Release(gstate);
388
389 return SRD_ERR_PYTHON;
7ee0c40b
BV
390}
391
287e2788
UH
392static void release_meta(GVariant *gvar)
393{
394 if (!gvar)
395 return;
396 g_variant_unref(gvar);
397}
398
e4bea07d 399PyDoc_STRVAR(Decoder_put_doc,
11c6995e
GS
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."
e4bea07d
GS
404);
405
d0a0ed03
BV
406static PyObject *Decoder_put(PyObject *self, PyObject *args)
407{
408 GSList *l;
4f75f1c1 409 PyObject *py_data, *py_res;
a8b72b05 410 struct srd_decoder_inst *di, *next_di;
d0a0ed03 411 struct srd_pd_output *pdo;
8a9f60b1 412 struct srd_proto_data pdata;
ee63c5dd 413 struct srd_proto_data_annotation pda;
c94631f1 414 struct srd_proto_data_binary pdb;
b8c8dc8a 415 struct srd_proto_data_logic pdl;
d0a0ed03
BV
416 uint64_t start_sample, end_sample;
417 int output_id;
2994587f 418 struct srd_pd_callback *cb;
514b2edc
UH
419 PyGILState_STATE gstate;
420
287e2788
UH
421 py_data = NULL;
422
514b2edc 423 gstate = PyGILState_Ensure();
d0a0ed03 424
a8b72b05 425 if (!(di = srd_inst_find_by_obj(NULL, self))) {
58572aed 426 /* Shouldn't happen. */
7a1712c4 427 srd_dbg("put(): self instance not found.");
514b2edc 428 goto err;
58572aed 429 }
d0a0ed03 430
c9bfccc6 431 if (!PyArg_ParseTuple(args, "KKiO", &start_sample, &end_sample,
3d14e7c9 432 &output_id, &py_data)) {
c9bfccc6
UH
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 */
514b2edc 438 goto err;
c9bfccc6 439 }
d0a0ed03
BV
440
441 if (!(l = g_slist_nth(di->pd_output, output_id))) {
d906d3f9 442 srd_err("Protocol decoder %s submitted invalid output ID %d.",
c9bfccc6 443 di->decoder->name, output_id);
514b2edc 444 goto err;
d0a0ed03
BV
445 }
446 pdo = l->data;
447
43dc0396
UH
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) {
755e4a1e
UH
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);
43dc0396 454 }
58572aed 455
8a9f60b1
UH
456 pdata.start_sample = start_sample;
457 pdata.end_sample = end_sample;
458 pdata.pdo = pdo;
459 pdata.data = NULL;
d0a0ed03
BV
460
461 switch (pdo->output_type) {
462 case SRD_OUTPUT_ANN:
463 /* Annotations are only fed to callbacks. */
32cfb920 464 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
ee63c5dd 465 pdata.data = &pda;
d75d8a7c 466 /* Convert from PyDict to srd_proto_data_annotation. */
8a9f60b1 467 if (convert_annotation(di, py_data, &pdata) != SRD_OK) {
d0a0ed03
BV
468 /* An error was already logged. */
469 break;
470 }
514b2edc 471 Py_BEGIN_ALLOW_THREADS
8a9f60b1 472 cb->cb(&pdata, cb->cb_data);
514b2edc 473 Py_END_ALLOW_THREADS
c1b2bbc1 474 release_annotation(pdata.data);
d0a0ed03
BV
475 }
476 break;
f2a5df42 477 case SRD_OUTPUT_PYTHON:
d0a0ed03
BV
478 for (l = di->next_di; l; l = l->next) {
479 next_di = l->data;
755e4a1e
UH
480 srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s "
481 "on oid %d (%s) to instance %s.", di->inst_id,
482 start_sample,
43dc0396 483 end_sample, output_type_name(pdo->output_type),
755e4a1e 484 output_id, pdo->proto_id, next_di->inst_id);
c9bfccc6 485 if (!(py_res = PyObject_CallMethod(
3d14e7c9
BV
486 next_di->py_inst, "decode", "KKO", start_sample,
487 end_sample, py_data))) {
201a85a8 488 srd_exception_catch("Calling %s decode() failed",
3d14e7c9 489 next_di->inst_id);
d0a0ed03
BV
490 }
491 Py_XDECREF(py_res);
492 }
3d14e7c9 493 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
7969d803
UH
494 /*
495 * Frontends aren't really supposed to get Python
496 * callbacks, but it's useful for testing.
497 */
8a9f60b1
UH
498 pdata.data = py_data;
499 cb->cb(&pdata, cb->cb_data);
3d14e7c9 500 }
d0a0ed03
BV
501 break;
502 case SRD_OUTPUT_BINARY:
d75d8a7c 503 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
c94631f1 504 pdata.data = &pdb;
d75d8a7c 505 /* Convert from PyDict to srd_proto_data_binary. */
8a9f60b1 506 if (convert_binary(di, py_data, &pdata) != SRD_OK) {
d75d8a7c
BV
507 /* An error was already logged. */
508 break;
509 }
514b2edc 510 Py_BEGIN_ALLOW_THREADS
8a9f60b1 511 cb->cb(&pdata, cb->cb_data);
514b2edc 512 Py_END_ALLOW_THREADS
c1b2bbc1 513 release_binary(pdata.data);
d75d8a7c 514 }
d0a0ed03 515 break;
ddcde186
UH
516 case SRD_OUTPUT_LOGIC:
517 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
b8c8dc8a 518 pdata.data = &pdl;
ddcde186
UH
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 }
b8c8dc8a
SA
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;
ddcde186
UH
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;
7ee0c40b
BV
535 case SRD_OUTPUT_META:
536 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
537 /* Annotations need converting from PyObject. */
8a9f60b1 538 if (convert_meta(&pdata, py_data) != SRD_OK) {
7ee0c40b
BV
539 /* An exception was already set up. */
540 break;
541 }
514b2edc 542 Py_BEGIN_ALLOW_THREADS
8a9f60b1 543 cb->cb(&pdata, cb->cb_data);
514b2edc 544 Py_END_ALLOW_THREADS
287e2788 545 release_meta(pdata.data);
7ee0c40b
BV
546 }
547 break;
d0a0ed03 548 default:
d906d3f9 549 srd_err("Protocol decoder %s submitted invalid output type %d.",
c9bfccc6 550 di->decoder->name, pdo->output_type);
d0a0ed03
BV
551 break;
552 }
553
514b2edc
UH
554 PyGILState_Release(gstate);
555
d0a0ed03 556 Py_RETURN_NONE;
514b2edc
UH
557
558err:
559 PyGILState_Release(gstate);
560
561 return NULL;
d0a0ed03
BV
562}
563
e4bea07d 564PyDoc_STRVAR(Decoder_register_doc,
11c6995e 565 "Register a new output stream."
e4bea07d
GS
566);
567
568static PyObject *Decoder_register(PyObject *self,
569 PyObject *args, PyObject *kwargs)
d0a0ed03 570{
a8b72b05 571 struct srd_decoder_inst *di;
7ee0c40b
BV
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;
7969d803 578 char *keywords[] = { "output_type", "proto_id", "meta", NULL };
514b2edc 579 PyGILState_STATE gstate;
7d82e3c1
GS
580 gboolean is_meta;
581 GSList *l;
582 struct srd_pd_output *cmp;
514b2edc
UH
583
584 gstate = PyGILState_Ensure();
7ee0c40b
BV
585
586 meta_type_py = NULL;
587 meta_type_gv = NULL;
588 meta_name = meta_descr = NULL;
d0a0ed03 589
a8b72b05 590 if (!(di = srd_inst_find_by_obj(NULL, self))) {
d0a0ed03 591 PyErr_SetString(PyExc_Exception, "decoder instance not found");
514b2edc 592 goto err;
d0a0ed03
BV
593 }
594
7969d803 595 /* Default to instance ID, which defaults to class ID. */
7ee0c40b
BV
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)) {
511e2123 600 /* Let Python raise this exception. */
514b2edc 601 goto err;
d0a0ed03
BV
602 }
603
7ee0c40b 604 /* Check if the meta value's type is supported. */
7d82e3c1
GS
605 is_meta = output_type == SRD_OUTPUT_META;
606 if (is_meta) {
7ee0c40b
BV
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 {
201a85a8 612 PyErr_Format(PyExc_TypeError, "Unsupported type.");
514b2edc 613 goto err;
7ee0c40b
BV
614 }
615 }
616
7d82e3c1
GS
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
077fa8ac 639 pdo = g_malloc(sizeof(struct srd_pd_output));
7ee0c40b
BV
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
514b2edc
UH
656 PyGILState_Release(gstate);
657
755e4a1e
UH
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
7ee0c40b 662 return py_new_output_id;
514b2edc
UH
663
664err:
665 PyGILState_Release(gstate);
666
667 return NULL;
7ee0c40b
BV
668}
669
21dfd91d
UH
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;
4e7ccaf9
UH
685 default:
686 return -1;
21dfd91d
UH
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;
514b2edc
UH
708 PyGILState_STATE gstate;
709
21dfd91d
UH
710 if (!di) {
711 srd_err("Invalid decoder instance.");
712 return NULL;
713 }
714
73578d2e
UH
715 gstate = PyGILState_Ensure();
716
21dfd91d
UH
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. */
3d9e87aa 723 PyTuple_SetItem(py_pinvalues, i, PyLong_FromUnsignedLong(0xff));
21dfd91d 724 } else {
4564e8e5 725 sample_pos = di->inbuf + ((di->abs_cur_samplenum - di->abs_start_samplenum) * di->data_unitsize);
21dfd91d
UH
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;
3d9e87aa 729 PyTuple_SetItem(py_pinvalues, i, PyLong_FromUnsignedLong(sample));
21dfd91d
UH
730 }
731 }
732
514b2edc
UH
733 PyGILState_Release(gstate);
734
21dfd91d
UH
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 *
1cb40e10 743 * @param di The decoder instance to use. Must not be NULL.
21dfd91d
UH
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 */
1cb40e10
GS
750static int create_term_list(struct srd_decoder_inst *di,
751 PyObject *py_dict, GSList **term_list)
21dfd91d
UH
752{
753 Py_ssize_t pos = 0;
754 PyObject *py_key, *py_value;
755 struct srd_term *term;
1cb40e10 756 int64_t num_samples_to_skip;
21dfd91d 757 char *term_str;
514b2edc 758 PyGILState_STATE gstate;
21dfd91d
UH
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
514b2edc
UH
766 gstate = PyGILState_Ensure();
767
21dfd91d
UH
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. */
21dfd91d
UH
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.");
514b2edc 776 goto err;
21dfd91d 777 }
35c10c0e 778 term = g_malloc(sizeof(struct srd_term));
21dfd91d
UH
779 term->type = get_term_type(term_str);
780 term->channel = PyLong_AsLong(py_key);
1cb40e10
GS
781 if (term->channel < 0 || term->channel >= di->dec_num_channels)
782 term->type = SRD_TERM_ALWAYS_FALSE;
21dfd91d
UH
783 g_free(term_str);
784 } else if (PyUnicode_Check(py_key)) {
785 /* The key is a string. */
1cb40e10 786 /* TODO: Check if the key is "skip". */
21dfd91d
UH
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.");
514b2edc 789 goto err;
21dfd91d 790 }
35c10c0e 791 term = g_malloc(sizeof(struct srd_term));
21dfd91d
UH
792 term->type = SRD_TERM_SKIP;
793 term->num_samples_to_skip = num_samples_to_skip;
794 term->num_samples_already_skipped = 0;
99e26489 795 if (num_samples_to_skip < 0)
1cb40e10 796 term->type = SRD_TERM_ALWAYS_FALSE;
21dfd91d
UH
797 } else {
798 srd_err("Term key is neither a string nor a number.");
514b2edc 799 goto err;
21dfd91d
UH
800 }
801
802 /* Add the term to the list of terms. */
803 *term_list = g_slist_append(*term_list, term);
804 }
805
514b2edc
UH
806 PyGILState_Release(gstate);
807
21dfd91d 808 return SRD_OK;
514b2edc
UH
809
810err:
811 PyGILState_Release(gstate);
812
813 return SRD_ERR;
21dfd91d
UH
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;
514b2edc 833 PyGILState_STATE gstate;
21dfd91d
UH
834
835 if (!self || !args)
836 return SRD_ERR_ARG;
837
514b2edc
UH
838 gstate = PyGILState_Ensure();
839
21dfd91d
UH
840 /* Get the decoder instance. */
841 if (!(di = srd_inst_find_by_obj(NULL, self))) {
842 PyErr_SetString(PyExc_Exception, "decoder instance not found");
514b2edc 843 goto err;
21dfd91d
UH
844 }
845
04383ea8
GS
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__);
514b2edc 852 goto err;
04383ea8
GS
853 }
854
6e19f325
GS
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)) {
21dfd91d 864 /* Let Python raise this exception. */
514b2edc 865 goto err;
21dfd91d 866 }
6e19f325
GS
867 if (py_conds == Py_None) {
868 /* 'py_conds' is None. */
514b2edc 869 goto ret_9999;
6e19f325 870 } else if (PyList_Check(py_conds)) {
21dfd91d
UH
871 /* 'py_conds' is a list. */
872 py_conditionlist = py_conds;
873 num_conditions = PyList_Size(py_conditionlist);
874 if (num_conditions == 0)
514b2edc 875 goto ret_9999; /* The PD invoked self.wait([]). */
733047ed 876 Py_INCREF(py_conditionlist);
21dfd91d
UH
877 } else if (PyDict_Check(py_conds)) {
878 /* 'py_conds' is a dict. */
879 if (PyDict_Size(py_conds) == 0)
514b2edc 880 goto ret_9999; /* The PD invoked self.wait({}). */
21dfd91d
UH
881 /* Make a list and put the dict in there for convenience. */
882 py_conditionlist = PyList_New(1);
733047ed 883 Py_INCREF(py_conds);
21dfd91d
UH
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.");
514b2edc 888 goto err;
21dfd91d
UH
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. */
1cb40e10 907 if ((ret = create_term_list(di, py_dict, &term_list)) < 0)
21dfd91d
UH
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
514b2edc
UH
916 PyGILState_Release(gstate);
917
21dfd91d 918 return ret;
514b2edc
UH
919
920err:
921 PyGILState_Release(gstate);
922
923 return SRD_ERR;
924
925ret_9999:
926 PyGILState_Release(gstate);
927
928 return 9999;
21dfd91d
UH
929}
930
96e1cee7
GS
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);
35c10c0e 956 term = g_malloc(sizeof(*term));
96e1cee7
GS
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
e4bea07d 966PyDoc_STRVAR(Decoder_wait_doc,
11c6995e
GS
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"
e4bea07d
GS
981);
982
21dfd91d
UH
983static PyObject *Decoder_wait(PyObject *self, PyObject *args)
984{
985 int ret;
96e1cee7 986 uint64_t skip_count;
21dfd91d
UH
987 unsigned int i;
988 gboolean found_match;
989 struct srd_decoder_inst *di;
e2768fbc 990 PyObject *py_pinvalues, *py_matched, *py_samplenum;
514b2edc 991 PyGILState_STATE gstate;
21dfd91d
UH
992
993 if (!self || !args)
994 return NULL;
995
514b2edc
UH
996 gstate = PyGILState_Ensure();
997
21dfd91d
UH
998 if (!(di = srd_inst_find_by_obj(NULL, self))) {
999 PyErr_SetString(PyExc_Exception, "decoder instance not found");
514b2edc 1000 PyGILState_Release(gstate);
21dfd91d
UH
1001 Py_RETURN_NONE;
1002 }
1003
1004 ret = set_new_condition_list(self, args);
04383ea8
GS
1005 if (ret < 0) {
1006 srd_dbg("%s: %s: Aborting wait().", di->inst_id, __func__);
514b2edc 1007 goto err;
04383ea8 1008 }
21dfd91d 1009 if (ret == 9999) {
96e1cee7
GS
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__);
514b2edc 1027 goto err;
96e1cee7 1028 }
21dfd91d
UH
1029 }
1030
1031 while (1) {
514b2edc
UH
1032
1033 Py_BEGIN_ALLOW_THREADS
1034
04383ea8 1035 /* Wait for new samples to process, or termination request. */
21dfd91d 1036 g_mutex_lock(&di->data_mutex);
04383ea8 1037 while (!di->got_new_samples && !di->want_wait_terminate)
21dfd91d
UH
1038 g_cond_wait(&di->got_new_samples_cond, &di->data_mutex);
1039
04383ea8
GS
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;
60d4764a
UH
1048
1049 /* Ignore return value for now, should never be negative. */
1050 (void)process_samples_until_condition_match(di, &found_match);
21dfd91d 1051
514b2edc
UH
1052 Py_END_ALLOW_THREADS
1053
21dfd91d
UH
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. */
3d9e87aa 1057 py_samplenum = PyLong_FromUnsignedLongLong(di->abs_cur_samplenum);
e2768fbc
UH
1058 PyObject_SetAttrString(di->py_inst, "samplenum", py_samplenum);
1059 Py_DECREF(py_samplenum);
21dfd91d
UH
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);
e2768fbc 1066 Py_DECREF(py_matched);
21dfd91d
UH
1067 match_array_free(di);
1068 } else {
1069 PyObject_SetAttrString(di->py_inst, "matched", Py_None);
1070 }
fa168be6 1071
21dfd91d
UH
1072 py_pinvalues = get_current_pinvalues(di);
1073
1074 g_mutex_unlock(&di->data_mutex);
1075
514b2edc
UH
1076 PyGILState_Release(gstate);
1077
21dfd91d
UH
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;
4564e8e5
UH
1084 di->abs_start_samplenum = 0;
1085 di->abs_end_samplenum = 0;
21dfd91d
UH
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
819e5089
GS
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
04383ea8
GS
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);
514b2edc 1116 goto err;
04383ea8
GS
1117 }
1118
21dfd91d
UH
1119 g_mutex_unlock(&di->data_mutex);
1120 }
1121
514b2edc
UH
1122 PyGILState_Release(gstate);
1123
21dfd91d 1124 Py_RETURN_NONE;
514b2edc
UH
1125
1126err:
1127 PyGILState_Release(gstate);
1128
1129 return NULL;
21dfd91d
UH
1130}
1131
e4bea07d 1132PyDoc_STRVAR(Decoder_has_channel_doc,
11c6995e
GS
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"
e4bea07d
GS
1138);
1139
21dfd91d
UH
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{
cd8d9188 1152 int idx, count;
21dfd91d 1153 struct srd_decoder_inst *di;
514b2edc 1154 PyGILState_STATE gstate;
234cbf50 1155 PyObject *bool_ret;
21dfd91d
UH
1156
1157 if (!self || !args)
1158 return NULL;
1159
514b2edc
UH
1160 gstate = PyGILState_Ensure();
1161
21dfd91d
UH
1162 if (!(di = srd_inst_find_by_obj(NULL, self))) {
1163 PyErr_SetString(PyExc_Exception, "decoder instance not found");
514b2edc 1164 goto err;
21dfd91d
UH
1165 }
1166
cd8d9188
GS
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)) {
21dfd91d 1172 /* Let Python raise this exception. */
514b2edc 1173 goto err;
21dfd91d
UH
1174 }
1175
cd8d9188
GS
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");
514b2edc 1181 goto err;
21dfd91d
UH
1182 }
1183
514b2edc
UH
1184 PyGILState_Release(gstate);
1185
234cbf50
GS
1186 bool_ret = (di->dec_channelmap[idx] == -1) ? Py_False : Py_True;
1187 Py_INCREF(bool_ret);
1188 return bool_ret;
514b2edc
UH
1189
1190err:
1191 PyGILState_Release(gstate);
1192
1193 return NULL;
21dfd91d
UH
1194}
1195
e4bea07d
GS
1196PyDoc_STRVAR(Decoder_doc, "sigrok Decoder base class");
1197
d0a0ed03 1198static PyMethodDef Decoder_methods[] = {
e4bea07d
GS
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 },
7337906c 1215 ALL_ZERO,
d0a0ed03
BV
1216};
1217
21dfd91d
UH
1218/**
1219 * Create the sigrokdecode.Decoder type.
1220 *
201a85a8 1221 * @return The new type object.
21dfd91d 1222 *
201a85a8
DE
1223 * @private
1224 */
1225SRD_PRIV PyObject *srd_Decoder_type_new(void)
1226{
1227 PyType_Spec spec;
1228 PyType_Slot slots[] = {
e4bea07d 1229 { Py_tp_doc, Decoder_doc },
201a85a8
DE
1230 { Py_tp_methods, Decoder_methods },
1231 { Py_tp_new, (void *)&PyType_GenericNew },
7337906c 1232 ALL_ZERO,
201a85a8 1233 };
514b2edc
UH
1234 PyObject *py_obj;
1235 PyGILState_STATE gstate;
1236
1237 gstate = PyGILState_Ensure();
1238
201a85a8
DE
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
514b2edc
UH
1245 py_obj = PyType_FromSpec(&spec);
1246
1247 PyGILState_Release(gstate);
1248
1249 return py_obj;
201a85a8 1250}