blob: 83a6dfb04bc5333c8983ec458421a4684ab84329 [file] [log] [blame]
Bert Vermeulenb2c19612011-12-04 10:33:02 +01001/*
Uwe Hermann50bd5d22013-04-23 22:27:20 +02002 * This file is part of the libsigrokdecode project.
Bert Vermeulenb2c19612011-12-04 10:33:02 +01003 *
4 * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +01005 * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
Bert Vermeulenb2c19612011-12-04 10:33:02 +01006 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
Uwe Hermannc1f86f02013-05-03 14:49:21 +020021#include "libsigrokdecode.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
22#include "libsigrokdecode-internal.h"
Bert Vermeulen7ce77752012-01-10 00:25:16 +010023#include "config.h"
Bert Vermeulenb2c19612011-12-04 10:33:02 +010024#include <glib.h>
Bert Vermeulen1aef2f92011-12-15 03:31:31 +010025#include <inttypes.h>
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010026#include <stdlib.h>
Bert Vermeulen32cfb922013-09-12 23:54:43 +020027#include <stdint.h>
Bert Vermeulenb2c19612011-12-04 10:33:02 +010028
Uwe Hermann57790bc2013-02-09 21:44:11 +010029/** @cond PRIVATE */
30
Bert Vermeulenfe9d91a2013-11-16 23:14:50 +010031extern GSList *sessions;
Bert Vermeulenb2c19612011-12-04 10:33:02 +010032
Uwe Hermannc9bfccc2012-02-08 22:39:30 +010033/* type_logic.c */
Uwe Hermann55c3c5f2012-02-09 19:11:53 +010034extern SRD_PRIV PyTypeObject srd_logic_type;
Bert Vermeulenb2c19612011-12-04 10:33:02 +010035
Uwe Hermann57790bc2013-02-09 21:44:11 +010036/** @endcond */
37
Bert Vermeulenb2c19612011-12-04 10:33:02 +010038/**
Bert Vermeulen190b71c2013-11-16 22:58:28 +010039 * @file
Bert Vermeulenb2c19612011-12-04 10:33:02 +010040 *
Bert Vermeulen190b71c2013-11-16 22:58:28 +010041 * Decoder instance handling.
Bert Vermeulenb2c19612011-12-04 10:33:02 +010042 */
Uwe Hermann48954182013-02-09 22:25:15 +010043
44/**
45 * @defgroup grp_instances Decoder instances
46 *
47 * Decoder instance handling.
48 *
49 * @{
50 */
51
Bert Vermeulen7ce77752012-01-10 00:25:16 +010052/**
Uwe Hermannb33b8aa2012-03-25 14:49:11 +020053 * Set one or more options in a decoder instance.
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010054 *
Uwe Hermann361fdca2012-03-15 22:00:24 +010055 * Handled options are removed from the hash.
56 *
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010057 * @param di Decoder instance.
58 * @param options A GHashTable of options to set.
59 *
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010060 * @return SRD_OK upon success, a (negative) error code otherwise.
Uwe Hermann8c664ca2013-05-03 14:45:49 +020061 *
62 * @since 0.1.0
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010063 */
Uwe Hermannb33b8aa2012-03-25 14:49:11 +020064SRD_API int srd_inst_option_set(struct srd_decoder_inst *di,
Bert Vermeulen0ff2d192013-03-19 01:01:25 +010065 GHashTable *options)
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010066{
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +010067 struct srd_decoder_option *sdo;
68 PyObject *py_di_options, *py_optval;
Bert Vermeulen2f395bf2013-03-19 01:47:53 +010069 GVariant *value;
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +010070 GSList *l;
71 double val_double;
Bert Vermeulen2f395bf2013-03-19 01:47:53 +010072 gint64 val_int;
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +010073 int ret;
Bert Vermeulen2f395bf2013-03-19 01:47:53 +010074 const char *val_str;
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010075
Uwe Hermann3af0e342013-10-23 19:23:40 +020076 if (!di) {
77 srd_err("Invalid decoder instance.");
78 return SRD_ERR_ARG;
79 }
80
81 if (!options) {
82 srd_err("Invalid options GHashTable.");
83 return SRD_ERR_ARG;
84 }
85
Uwe Hermannc9bfccc2012-02-08 22:39:30 +010086 if (!PyObject_HasAttrString(di->decoder->py_dec, "options")) {
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010087 /* Decoder has no options. */
Bert Vermeulene431d9c2012-01-18 22:59:14 +010088 if (g_hash_table_size(options) == 0) {
89 /* No options provided. */
90 return SRD_OK;
91 } else {
92 srd_err("Protocol decoder has no options.");
93 return SRD_ERR_ARG;
94 }
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010095 return SRD_OK;
Bert Vermeulene431d9c2012-01-18 22:59:14 +010096 }
Bert Vermeulen0bdadba2012-01-17 03:37:34 +010097
98 ret = SRD_ERR_PYTHON;
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +010099 py_optval = NULL;
Bert Vermeulen119d6252013-10-17 16:27:54 +0200100
101 /*
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +0100102 * The 'options' tuple is a class variable, but we need to
Bert Vermeulen119d6252013-10-17 16:27:54 +0200103 * change it. Changing it directly will affect the entire class,
104 * so we need to create a new object for it, and populate that
105 * instead.
106 */
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100107 if (!(py_di_options = PyObject_GetAttrString(di->py_inst, "options")))
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100108 goto err_out;
Bert Vermeulen119d6252013-10-17 16:27:54 +0200109 Py_DECREF(py_di_options);
110 py_di_options = PyDict_New();
111 PyObject_SetAttrString(di->py_inst, "options", py_di_options);
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100112
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +0100113 for (l = di->decoder->options; l; l = l->next) {
114 sdo = l->data;
115 if ((value = g_hash_table_lookup(options, sdo->id))) {
116 /* A value was supplied for this option. */
117 if (!g_variant_type_equal(g_variant_get_type(value),
118 g_variant_get_type(sdo->def))) {
119 srd_err("Option '%s' should have the same type "
120 "as the default value.", sdo->id);
121 goto err_out;
122 }
123 } else {
124 /* Use default for this option. */
125 value = sdo->def;
126 }
127 if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
128 val_str = g_variant_get_string(value, NULL);
129 if (!(py_optval = PyUnicode_FromString(val_str))) {
130 /* Some UTF-8 encoding error. */
131 PyErr_Clear();
132 srd_err("Option '%s' requires a UTF-8 string value.", sdo->id);
133 goto err_out;
134 }
135 } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_INT64)) {
136 val_int = g_variant_get_int64(value);
137 if (!(py_optval = PyLong_FromLong(val_int))) {
138 /* ValueError Exception */
139 PyErr_Clear();
140 srd_err("Option '%s' has invalid integer value.", sdo->id);
141 goto err_out;
142 }
143 } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_DOUBLE)) {
Joel Holdsworth24a3d8d2014-03-11 22:58:24 +0100144 val_double = g_variant_get_double(value);
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +0100145 if (!(py_optval = PyFloat_FromDouble(val_double))) {
146 /* ValueError Exception */
147 PyErr_Clear();
148 srd_err("Option '%s' has invalid float value.", sdo->id);
149 goto err_out;
150 }
151 }
152 if (PyDict_SetItemString(py_di_options, sdo->id, py_optval) == -1)
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100153 goto err_out;
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +0100154 /* Not harmful even if we used the default. */
155 g_hash_table_remove(options, sdo->id);
156 }
157 if (g_hash_table_size(options) != 0)
158 srd_warn("Unknown options specified for '%s'", di->inst_id);
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100159
160 ret = SRD_OK;
161
162err_out:
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +0100163 Py_XDECREF(py_optval);
Bert Vermeulen7fc7bde2013-10-16 11:10:27 +0200164 if (PyErr_Occurred()) {
Uwe Hermannaafeeae2012-03-25 15:08:16 +0200165 srd_exception_catch("Stray exception in srd_inst_option_set().");
Bert Vermeulen7fc7bde2013-10-16 11:10:27 +0200166 ret = SRD_ERR_PYTHON;
167 }
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100168
169 return ret;
170}
171
Uwe Hermann6a155972014-04-13 19:57:43 +0200172/* Helper GComparefunc for g_slist_find_custom() in srd_inst_channel_set_all() */
173static gint compare_channel_id(const struct srd_channel *pdch,
174 const char *channel_id)
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100175{
Uwe Hermann6a155972014-04-13 19:57:43 +0200176 return strcmp(pdch->id, channel_id);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100177}
178
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100179/**
Uwe Hermann6a155972014-04-13 19:57:43 +0200180 * Set all channels in a decoder instance.
Uwe Hermannb33b8aa2012-03-25 14:49:11 +0200181 *
Uwe Hermann6a155972014-04-13 19:57:43 +0200182 * This function sets _all_ channels for the specified decoder instance, i.e.,
183 * it overwrites any channels that were already defined (if any).
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100184 *
185 * @param di Decoder instance.
Uwe Hermann6a155972014-04-13 19:57:43 +0200186 * @param new_channels A GHashTable of channels to set. Key is channel name,
187 * value is the channel number. Samples passed to this
188 * instance will be arranged in this order.
Daniel Elstner9eec72c2014-02-20 06:24:23 +0100189 * @param unit_size Number of bytes per sample in the data stream to be passed
Uwe Hermann6a155972014-04-13 19:57:43 +0200190 * to the decoder. The highest channel index specified in the
191 * channel map must lie within a sample unit.
Bert Vermeulen12243c22012-02-12 14:18:32 +0100192 *
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100193 * @return SRD_OK upon success, a (negative) error code otherwise.
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200194 *
195 * @since 0.1.0
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100196 */
Uwe Hermann6a155972014-04-13 19:57:43 +0200197SRD_API int srd_inst_channel_set_all(struct srd_decoder_inst *di,
198 GHashTable *new_channels, int unit_size)
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100199{
Uwe Hermann6a155972014-04-13 19:57:43 +0200200 GVariant *channel_val;
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100201 GList *l;
202 GSList *sl;
Uwe Hermann6a155972014-04-13 19:57:43 +0200203 struct srd_channel *pdch;
204 int *new_channelmap, new_channelnum, num_required_channels, i;
205 char *channel_id;
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100206
Bert Vermeulen170d0e22014-04-15 00:46:45 +0200207 srd_dbg("set channels called for instance %s with list of %d probes, "
208 "unitsize %d", di->inst_id, g_hash_table_size(new_channels), unit_size);
Bert Vermeulence46bee2012-01-27 08:21:58 +0100209
Uwe Hermann6a155972014-04-13 19:57:43 +0200210 if (g_hash_table_size(new_channels) == 0)
211 /* No channels provided. */
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100212 return SRD_OK;
213
Uwe Hermann6a155972014-04-13 19:57:43 +0200214 if (di->dec_num_channels == 0) {
215 /* Decoder has no channels. */
216 srd_err("Protocol decoder %s has no channels to define.",
Uwe Hermannc9bfccc2012-02-08 22:39:30 +0100217 di->decoder->name);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100218 return SRD_ERR_ARG;
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100219 }
220
Uwe Hermann6a155972014-04-13 19:57:43 +0200221 new_channelmap = NULL;
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100222
Uwe Hermann6a155972014-04-13 19:57:43 +0200223 if (!(new_channelmap = g_try_malloc(sizeof(int) * di->dec_num_channels))) {
224 srd_err("Failed to g_malloc() new channel map.");
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100225 return SRD_ERR_MALLOC;
226 }
227
Uwe Hermann38ff5042013-02-02 12:18:29 +0100228 /*
Uwe Hermann6a155972014-04-13 19:57:43 +0200229 * For now, map all indexes to channel -1 (can be overridden later).
230 * This -1 is interpreted as an unspecified channel later.
Uwe Hermann38ff5042013-02-02 12:18:29 +0100231 */
Uwe Hermann6a155972014-04-13 19:57:43 +0200232 for (i = 0; i < di->dec_num_channels; i++)
233 new_channelmap[i] = -1;
Uwe Hermann38ff5042013-02-02 12:18:29 +0100234
Uwe Hermann6a155972014-04-13 19:57:43 +0200235 for (l = g_hash_table_get_keys(new_channels); l; l = l->next) {
236 channel_id = l->data;
237 channel_val = g_hash_table_lookup(new_channels, channel_id);
238 if (!g_variant_is_of_type(channel_val, G_VARIANT_TYPE_INT32)) {
239 /* Channel name was specified without a value. */
240 srd_err("No channel number was specified for %s.",
241 channel_id);
242 g_free(new_channelmap);
Bert Vermeulenbe873262012-01-23 19:34:23 +0100243 return SRD_ERR_ARG;
244 }
Uwe Hermann6a155972014-04-13 19:57:43 +0200245 new_channelnum = g_variant_get_int32(channel_val);
246 if (new_channelnum >= 8 * unit_size) {
247 srd_err("Channel index %d not within data unit (%d bit).",
248 new_channelnum, 8 * unit_size);
249 g_free(new_channelmap);
Daniel Elstner9eec72c2014-02-20 06:24:23 +0100250 return SRD_ERR_ARG;
251 }
Uwe Hermann6a155972014-04-13 19:57:43 +0200252 if (!(sl = g_slist_find_custom(di->decoder->channels, channel_id,
253 (GCompareFunc)compare_channel_id))) {
254 /* Fall back on optional channels. */
255 if (!(sl = g_slist_find_custom(di->decoder->opt_channels,
256 channel_id, (GCompareFunc) compare_channel_id))) {
257 srd_err("Protocol decoder %s has no channel "
258 "'%s'.", di->decoder->name, channel_id);
259 g_free(new_channelmap);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100260 return SRD_ERR_ARG;
261 }
262 }
Uwe Hermann6a155972014-04-13 19:57:43 +0200263 pdch = sl->data;
264 new_channelmap[pdch->order] = new_channelnum;
265 srd_dbg("Setting channel mapping: %s (index %d) = channel %d.",
266 pdch->id, pdch->order, new_channelnum);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100267 }
Daniel Elstner9eec72c2014-02-20 06:24:23 +0100268 di->data_unitsize = unit_size;
Uwe Hermann38ff5042013-02-02 12:18:29 +0100269
Uwe Hermann6a155972014-04-13 19:57:43 +0200270 srd_dbg("Final channel map:");
271 num_required_channels = g_slist_length(di->decoder->channels);
272 for (i = 0; i < di->dec_num_channels; i++) {
273 srd_dbg(" - index %d = channel %d (%s)", i, new_channelmap[i],
274 (i < num_required_channels) ? "required" : "optional");
Uwe Hermann38ff5042013-02-02 12:18:29 +0100275 }
276
Uwe Hermann6a155972014-04-13 19:57:43 +0200277 /* Report an error if not all required channels were specified. */
278 for (i = 0; i < num_required_channels; i++) {
279 if (new_channelmap[i] != -1)
Uwe Hermann9bf7f712014-01-31 00:13:32 +0100280 continue;
Uwe Hermann6a155972014-04-13 19:57:43 +0200281 pdch = g_slist_nth(di->decoder->channels, i)->data;
282 srd_err("Required channel '%s' (index %d) was not specified.",
283 pdch->id, i);
Uwe Hermann9bf7f712014-01-31 00:13:32 +0100284 return SRD_ERR;
285 }
286
Uwe Hermann6a155972014-04-13 19:57:43 +0200287 g_free(di->dec_channelmap);
288 di->dec_channelmap = new_channelmap;
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100289
290 return SRD_OK;
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100291}
292
293/**
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100294 * Create a new protocol decoder instance.
295 *
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200296 * @param sess The session holding the protocol decoder instance.
Uwe Hermann38ff5042013-02-02 12:18:29 +0100297 * @param decoder_id Decoder 'id' field.
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100298 * @param options GHashtable of options which override the defaults set in
Uwe Hermann38ff5042013-02-02 12:18:29 +0100299 * the decoder class. May be NULL.
Bert Vermeulen12243c22012-02-12 14:18:32 +0100300 *
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100301 * @return Pointer to a newly allocated struct srd_decoder_inst, or
Uwe Hermannc9bfccc2012-02-08 22:39:30 +0100302 * NULL in case of failure.
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200303 *
Bert Vermeulen69075812013-10-30 15:22:10 +0100304 * @since 0.3.0
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100305 */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200306SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess,
307 const char *decoder_id, GHashTable *options)
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100308{
Uwe Hermannc9bfccc2012-02-08 22:39:30 +0100309 int i;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100310 struct srd_decoder *dec;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100311 struct srd_decoder_inst *di;
312 char *inst_id;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100313
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100314 srd_dbg("Creating new %s instance.", decoder_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100315
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200316 if (session_is_valid(sess) != SRD_OK) {
317 srd_err("Invalid session.");
318 return NULL;
319 }
320
Bert Vermeulen9d122fd2012-02-14 03:43:28 +0100321 if (!(dec = srd_decoder_get_by_id(decoder_id))) {
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100322 srd_err("Protocol decoder %s not found.", decoder_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100323 return NULL;
324 }
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100325
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100326 if (!(di = g_try_malloc0(sizeof(struct srd_decoder_inst)))) {
Uwe Hermanna61ece22012-02-10 00:06:58 +0100327 srd_err("Failed to g_malloc() instance.");
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100328 return NULL;
329 }
330
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100331 di->decoder = dec;
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200332 di->sess = sess;
Uwe Hermann38ff5042013-02-02 12:18:29 +0100333 if (options) {
334 inst_id = g_hash_table_lookup(options, "id");
335 di->inst_id = g_strdup(inst_id ? inst_id : decoder_id);
336 g_hash_table_remove(options, "id");
337 } else
338 di->inst_id = g_strdup(decoder_id);
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100339
Uwe Hermann361fdca2012-03-15 22:00:24 +0100340 /*
Uwe Hermann6a155972014-04-13 19:57:43 +0200341 * Prepare a default channel map, where samples come in the
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100342 * order in which the decoder class defined them.
343 */
Uwe Hermann6a155972014-04-13 19:57:43 +0200344 di->dec_num_channels = g_slist_length(di->decoder->channels) +
345 g_slist_length(di->decoder->opt_channels);
346 if (di->dec_num_channels) {
347 if (!(di->dec_channelmap =
348 g_try_malloc(sizeof(int) * di->dec_num_channels))) {
349 srd_err("Failed to g_malloc() channel map.");
Bert Vermeulen19a90ba2012-01-21 19:45:04 +0100350 g_free(di);
351 return NULL;
352 }
Uwe Hermann6a155972014-04-13 19:57:43 +0200353 for (i = 0; i < di->dec_num_channels; i++)
354 di->dec_channelmap[i] = i;
355 di->data_unitsize = (di->dec_num_channels + 7) / 8;
Bert Vermeulen37b94c22013-11-26 16:05:54 +0100356 /*
357 * Will be used to prepare a sample at every iteration
358 * of the instance's decode() method.
359 */
Uwe Hermann6a155972014-04-13 19:57:43 +0200360 if (!(di->channel_samples = g_try_malloc(di->dec_num_channels))) {
Bert Vermeulen37b94c22013-11-26 16:05:54 +0100361 srd_err("Failed to g_malloc() sample buffer.");
Uwe Hermann6a155972014-04-13 19:57:43 +0200362 g_free(di->dec_channelmap);
Bert Vermeulen37b94c22013-11-26 16:05:54 +0100363 g_free(di);
364 return NULL;
365 }
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100366 }
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100367
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100368 /* Create a new instance of this decoder class. */
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100369 if (!(di->py_inst = PyObject_CallObject(dec->py_dec, NULL))) {
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100370 if (PyErr_Occurred())
Uwe Hermannaafeeae2012-03-25 15:08:16 +0200371 srd_exception_catch("failed to create %s instance: ",
Bert Vermeulen69075812013-10-30 15:22:10 +0100372 decoder_id);
Uwe Hermann6a155972014-04-13 19:57:43 +0200373 g_free(di->dec_channelmap);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100374 g_free(di);
375 return NULL;
376 }
377
Uwe Hermann38ff5042013-02-02 12:18:29 +0100378 if (options && srd_inst_option_set(di, options) != SRD_OK) {
Uwe Hermann6a155972014-04-13 19:57:43 +0200379 g_free(di->dec_channelmap);
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100380 g_free(di);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100381 return NULL;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100382 }
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100383
384 /* Instance takes input from a frontend by default. */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200385 sess->di_list = g_slist_append(sess->di_list, di);
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100386
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100387 return di;
388}
389
Bert Vermeulen582c8472012-02-12 14:55:20 +0100390/**
391 * Stack a decoder instance on top of another.
392 *
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200393 * @param sess The session holding the protocol decoder instances.
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100394 * @param di_bottom The instance on top of which di_top will be stacked.
395 * @param di_top The instance to go on top.
Bert Vermeulen582c8472012-02-12 14:55:20 +0100396 *
397 * @return SRD_OK upon success, a (negative) error code otherwise.
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200398 *
Bert Vermeulen69075812013-10-30 15:22:10 +0100399 * @since 0.3.0
Bert Vermeulen582c8472012-02-12 14:55:20 +0100400 */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200401SRD_API int srd_inst_stack(struct srd_session *sess,
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100402 struct srd_decoder_inst *di_bottom,
403 struct srd_decoder_inst *di_top)
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100404{
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200405
406 if (session_is_valid(sess) != SRD_OK) {
407 srd_err("Invalid session.");
408 return SRD_ERR_ARG;
409 }
410
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100411 if (!di_bottom || !di_top) {
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100412 srd_err("Invalid from/to instance pair.");
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100413 return SRD_ERR_ARG;
414 }
415
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100416 if (g_slist_find(sess->di_list, di_top)) {
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100417 /* Remove from the unstacked list. */
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100418 sess->di_list = g_slist_remove(sess->di_list, di_top);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100419 }
420
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100421 /* Stack on top of source di. */
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100422 di_bottom->next_di = g_slist_append(di_bottom->next_di, di_top);
423
424 srd_dbg("Stacked %s on top of %s.", di_top->inst_id, di_bottom->inst_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100425
426 return SRD_OK;
427}
428
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100429/**
Uwe Hermann361fdca2012-03-15 22:00:24 +0100430 * Find a decoder instance by its instance ID.
431 *
432 * Only the bottom level of instances are searched -- instances already stacked
433 * on top of another one will not be found.
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100434 *
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200435 * @param sess The session holding the protocol decoder instance.
Uwe Hermanned2306a2012-03-18 14:16:50 +0100436 * @param inst_id The instance ID to be found.
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100437 *
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100438 * @return Pointer to struct srd_decoder_inst, or NULL if not found.
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200439 *
Bert Vermeulen69075812013-10-30 15:22:10 +0100440 * @since 0.3.0
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100441 */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200442SRD_API struct srd_decoder_inst *srd_inst_find_by_id(struct srd_session *sess,
443 const char *inst_id)
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100444{
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100445 GSList *l;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100446 struct srd_decoder_inst *tmp, *di;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100447
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200448 if (session_is_valid(sess) != SRD_OK) {
449 srd_err("Invalid session.");
450 return NULL;
451 }
452
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100453 di = NULL;
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200454 for (l = sess->di_list; l; l = l->next) {
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100455 tmp = l->data;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100456 if (!strcmp(tmp->inst_id, inst_id)) {
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100457 di = tmp;
458 break;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100459 }
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100460 }
461
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100462 return di;
463}
464
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200465static struct srd_decoder_inst *srd_sess_inst_find_by_obj(
466 struct srd_session *sess, const GSList *stack,
467 const PyObject *obj)
468{
469 const GSList *l;
470 struct srd_decoder_inst *tmp, *di;
471
472 if (session_is_valid(sess) != SRD_OK) {
473 srd_err("Invalid session.");
474 return NULL;
475 }
476
477 di = NULL;
478 for (l = stack ? stack : sess->di_list; di == NULL && l != NULL; l = l->next) {
479 tmp = l->data;
480 if (tmp->py_inst == obj)
481 di = tmp;
482 else if (tmp->next_di)
483 di = srd_sess_inst_find_by_obj(sess, tmp->next_di, obj);
484 }
485
486 return di;
487}
488
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100489/**
Uwe Hermann361fdca2012-03-15 22:00:24 +0100490 * Find a decoder instance by its Python object.
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100491 *
Uwe Hermann361fdca2012-03-15 22:00:24 +0100492 * I.e. find that instance's instantiation of the sigrokdecode.Decoder class.
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200493 * This will recurse to find the instance anywhere in the stack tree of all
494 * sessions.
Uwe Hermann361fdca2012-03-15 22:00:24 +0100495 *
496 * @param stack Pointer to a GSList of struct srd_decoder_inst, indicating the
497 * stack to search. To start searching at the bottom level of
498 * decoder instances, pass NULL.
Uwe Hermann511e2122012-02-10 09:29:38 +0100499 * @param obj The Python class instantiation.
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100500 *
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100501 * @return Pointer to struct srd_decoder_inst, or NULL if not found.
Uwe Hermann57790bc2013-02-09 21:44:11 +0100502 *
503 * @private
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200504 *
505 * @since 0.1.0
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100506 */
Uwe Hermannabeeed82012-03-16 15:12:54 +0100507SRD_PRIV struct srd_decoder_inst *srd_inst_find_by_obj(const GSList *stack,
Bert Vermeulen0ff2d192013-03-19 01:01:25 +0100508 const PyObject *obj)
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100509{
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200510 struct srd_decoder_inst *di;
511 struct srd_session *sess;
512 GSList *l;
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100513
514 di = NULL;
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200515 for (l = sessions; di == NULL && l != NULL; l = l->next) {
516 sess = l->data;
517 di = srd_sess_inst_find_by_obj(sess, stack, obj);
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100518 }
519
520 return di;
521}
522
Uwe Hermann57790bc2013-02-09 21:44:11 +0100523/** @private */
Bert Vermeulened416492013-10-30 16:30:05 +0100524SRD_PRIV int srd_inst_start(struct srd_decoder_inst *di)
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100525{
Bert Vermeulened416492013-10-30 16:30:05 +0100526 PyObject *py_res;
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100527 GSList *l;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100528 struct srd_decoder_inst *next_di;
Bert Vermeulened416492013-10-30 16:30:05 +0100529 int ret;
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100530
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100531 srd_dbg("Calling start() method on protocol decoder instance %s.",
Bert Vermeulened416492013-10-30 16:30:05 +0100532 di->inst_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100533
Bert Vermeulened416492013-10-30 16:30:05 +0100534 if (!(py_res = PyObject_CallMethod(di->py_inst, "start", NULL))) {
Uwe Hermannaafeeae2012-03-25 15:08:16 +0200535 srd_exception_catch("Protocol decoder instance %s: ",
Bert Vermeulened416492013-10-30 16:30:05 +0100536 di->inst_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100537 return SRD_ERR_PYTHON;
538 }
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100539 Py_DecRef(py_res);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100540
Bert Vermeulened416492013-10-30 16:30:05 +0100541 /* Start all the PDs stacked on top of this one. */
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100542 for (l = di->next_di; l; l = l->next) {
543 next_di = l->data;
Bert Vermeulened416492013-10-30 16:30:05 +0100544 if ((ret = srd_inst_start(next_di)) != SRD_OK)
545 return ret;
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100546 }
547
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100548 return SRD_OK;
549}
550
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100551/**
552 * Run the specified decoder function.
553 *
Bert Vermeulened416492013-10-30 16:30:05 +0100554 * @param di The decoder instance to call. Must not be NULL.
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100555 * @param start_samplenum The starting sample number for the buffer's sample
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100556 * set, relative to the start of capture.
Bert Vermeulened416492013-10-30 16:30:05 +0100557 * @param end_samplenum The ending sample number for the buffer's sample
558 * set, relative to the start of capture.
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100559 * @param inbuf The buffer to decode. Must not be NULL.
560 * @param inbuflen Length of the buffer. Must be > 0.
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100561 *
562 * @return SRD_OK upon success, a (negative) error code otherwise.
Uwe Hermann57790bc2013-02-09 21:44:11 +0100563 *
564 * @private
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200565 *
566 * @since 0.1.0
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100567 */
Bert Vermeulened416492013-10-30 16:30:05 +0100568SRD_PRIV int srd_inst_decode(const struct srd_decoder_inst *di,
569 uint64_t start_samplenum, uint64_t end_samplenum,
570 const uint8_t *inbuf, uint64_t inbuflen)
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100571{
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100572 PyObject *py_res;
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100573 srd_logic *logic;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100574
Uwe Hermann74bb0af2013-10-20 23:09:46 +0200575 srd_dbg("Calling decode() on instance %s with %" PRIu64 " bytes "
576 "starting at sample %" PRIu64 ".", di->inst_id, inbuflen,
577 start_samplenum);
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100578
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100579 /* Return an error upon unusable input. */
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100580 if (!di) {
581 srd_dbg("empty decoder instance");
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100582 return SRD_ERR_ARG;
583 }
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100584 if (!inbuf) {
585 srd_dbg("NULL buffer pointer");
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100586 return SRD_ERR_ARG;
587 }
588 if (inbuflen == 0) {
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100589 srd_dbg("empty buffer");
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100590 return SRD_ERR_ARG;
591 }
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100592
Uwe Hermann361fdca2012-03-15 22:00:24 +0100593 /*
594 * Create new srd_logic object. Each iteration around the PD's loop
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100595 * will fill one sample into this object.
596 */
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100597 logic = PyObject_New(srd_logic, &srd_logic_type);
598 Py_INCREF(logic);
Uwe Hermannabeeed82012-03-16 15:12:54 +0100599 logic->di = (struct srd_decoder_inst *)di;
Bert Vermeulen86528292012-01-15 23:20:39 +0100600 logic->start_samplenum = start_samplenum;
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100601 logic->itercnt = 0;
Uwe Hermannabeeed82012-03-16 15:12:54 +0100602 logic->inbuf = (uint8_t *)inbuf;
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100603 logic->inbuflen = inbuflen;
604 logic->sample = PyList_New(2);
605 Py_INCREF(logic->sample);
606
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100607 Py_IncRef(di->py_inst);
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100608 if (!(py_res = PyObject_CallMethod(di->py_inst, "decode",
Bert Vermeulened416492013-10-30 16:30:05 +0100609 "KKO", start_samplenum, end_samplenum, logic))) {
610 srd_exception_catch("Protocol decoder instance %s: ", di->inst_id);
Bert Vermeulen0ff2d192013-03-19 01:01:25 +0100611 return SRD_ERR_PYTHON;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100612 }
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100613 Py_DecRef(py_res);
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100614
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100615 return SRD_OK;
616}
617
Uwe Hermann57790bc2013-02-09 21:44:11 +0100618/** @private */
Bert Vermeulen12243c22012-02-12 14:18:32 +0100619SRD_PRIV void srd_inst_free(struct srd_decoder_inst *di)
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100620{
621 GSList *l;
622 struct srd_pd_output *pdo;
623
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100624 srd_dbg("Freeing instance %s", di->inst_id);
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100625
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100626 Py_DecRef(di->py_inst);
627 g_free(di->inst_id);
Uwe Hermann6a155972014-04-13 19:57:43 +0200628 g_free(di->dec_channelmap);
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100629 g_slist_free(di->next_di);
630 for (l = di->pd_output; l; l = l->next) {
631 pdo = l->data;
632 g_free(pdo->proto_id);
633 g_free(pdo);
634 }
635 g_slist_free(di->pd_output);
Bert Vermeulene592ac82013-05-05 17:20:13 +0200636 g_free(di);
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100637}
638
Uwe Hermann57790bc2013-02-09 21:44:11 +0100639/** @private */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200640SRD_PRIV void srd_inst_free_all(struct srd_session *sess, GSList *stack)
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100641{
642 GSList *l;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100643 struct srd_decoder_inst *di;
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100644
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200645 if (session_is_valid(sess) != SRD_OK) {
646 srd_err("Invalid session.");
647 return;
648 }
649
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100650 di = NULL;
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200651 for (l = stack ? stack : sess->di_list; di == NULL && l != NULL; l = l->next) {
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100652 di = l->data;
653 if (di->next_di)
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200654 srd_inst_free_all(sess, di->next_di);
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100655 srd_inst_free(di);
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100656 }
657 if (!stack) {
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200658 g_slist_free(sess->di_list);
659 sess->di_list = NULL;
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100660 }
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100661}
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100662
Uwe Hermann48954182013-02-09 22:25:15 +0100663/** @} */
664