blob: d0e9d0ac5f663626da3a7545b59f74beb450b666 [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
Marcus Comstedtf6c7ead2014-07-01 00:07:40 +020021#include "libsigrokdecode-internal.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
22#include "libsigrokdecode.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
Uwe Hermann23a29d22014-05-04 21:00:24 +020031extern SRD_PRIV 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{
Uwe Hermannd841d5b2014-08-14 18:51:11 +020067 struct srd_decoder_option *sdo;
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +010068 PyObject *py_di_options, *py_optval;
Bert Vermeulen2f395bf2013-03-19 01:47:53 +010069 GVariant *value;
Uwe Hermannd841d5b2014-08-14 18:51:11 +020070 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;
Uwe Hermannd841d5b2014-08-14 18:51:11 +020099 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
Uwe Hermannd841d5b2014-08-14 18:51:11 +0200113 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),
Uwe Hermannbd6594c2014-10-15 15:23:22 +0200118 g_variant_get_type(sdo->def))) {
Uwe Hermannd841d5b2014-08-14 18:51:11 +0200119 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)) {
144 val_double = g_variant_get_double(value);
145 if (!(py_optval = PyFloat_FromDouble(val_double))) {
146 /* ValueError Exception */
147 PyErr_Clear();
148 srd_err("Option '%s' has invalid float value.",
149 sdo->id);
150 goto err_out;
151 }
152 }
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +0100153 if (PyDict_SetItemString(py_di_options, sdo->id, py_optval) == -1)
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100154 goto err_out;
Uwe Hermannd841d5b2014-08-14 18:51:11 +0200155 /* Not harmful even if we used the default. */
156 g_hash_table_remove(options, sdo->id);
157 }
158 if (g_hash_table_size(options) != 0)
159 srd_warn("Unknown options specified for '%s'", di->inst_id);
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100160
161 ret = SRD_OK;
162
163err_out:
Bert Vermeulen84c1c0b2014-03-09 23:48:27 +0100164 Py_XDECREF(py_optval);
Bert Vermeulen7fc7bde2013-10-16 11:10:27 +0200165 if (PyErr_Occurred()) {
Uwe Hermannaafeeae2012-03-25 15:08:16 +0200166 srd_exception_catch("Stray exception in srd_inst_option_set().");
Bert Vermeulen7fc7bde2013-10-16 11:10:27 +0200167 ret = SRD_ERR_PYTHON;
168 }
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100169
170 return ret;
171}
172
Uwe Hermann6a155972014-04-13 19:57:43 +0200173/* Helper GComparefunc for g_slist_find_custom() in srd_inst_channel_set_all() */
174static gint compare_channel_id(const struct srd_channel *pdch,
175 const char *channel_id)
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100176{
Uwe Hermann6a155972014-04-13 19:57:43 +0200177 return strcmp(pdch->id, channel_id);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100178}
179
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100180/**
Uwe Hermann6a155972014-04-13 19:57:43 +0200181 * Set all channels in a decoder instance.
Uwe Hermannb33b8aa2012-03-25 14:49:11 +0200182 *
Uwe Hermann6a155972014-04-13 19:57:43 +0200183 * This function sets _all_ channels for the specified decoder instance, i.e.,
184 * it overwrites any channels that were already defined (if any).
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100185 *
186 * @param di Decoder instance.
Uwe Hermann6a155972014-04-13 19:57:43 +0200187 * @param new_channels A GHashTable of channels to set. Key is channel name,
188 * value is the channel number. Samples passed to this
189 * instance will be arranged in this order.
Daniel Elstner9eec72c2014-02-20 06:24:23 +0100190 * @param unit_size Number of bytes per sample in the data stream to be passed
Uwe Hermann6a155972014-04-13 19:57:43 +0200191 * to the decoder. The highest channel index specified in the
192 * channel map must lie within a sample unit.
Bert Vermeulen12243c22012-02-12 14:18:32 +0100193 *
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100194 * @return SRD_OK upon success, a (negative) error code otherwise.
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200195 *
Uwe Hermannc57d1012014-05-04 20:25:17 +0200196 * @since 0.3.0
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100197 */
Uwe Hermann6a155972014-04-13 19:57:43 +0200198SRD_API int srd_inst_channel_set_all(struct srd_decoder_inst *di,
199 GHashTable *new_channels, int unit_size)
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100200{
Uwe Hermann6a155972014-04-13 19:57:43 +0200201 GVariant *channel_val;
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100202 GList *l;
203 GSList *sl;
Uwe Hermann6a155972014-04-13 19:57:43 +0200204 struct srd_channel *pdch;
205 int *new_channelmap, new_channelnum, num_required_channels, i;
206 char *channel_id;
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100207
Uwe Hermannf714f8f2014-04-15 08:44:51 +0200208 srd_dbg("Setting channels for instance %s with list of %d channels, "
Uwe Hermannd841d5b2014-08-14 18:51:11 +0200209 "unitsize %d.", di->inst_id, g_hash_table_size(new_channels),
210 unit_size);
Bert Vermeulence46bee2012-01-27 08:21:58 +0100211
Uwe Hermann6a155972014-04-13 19:57:43 +0200212 if (g_hash_table_size(new_channels) == 0)
213 /* No channels provided. */
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100214 return SRD_OK;
215
Uwe Hermann6a155972014-04-13 19:57:43 +0200216 if (di->dec_num_channels == 0) {
217 /* Decoder has no channels. */
218 srd_err("Protocol decoder %s has no channels to define.",
Uwe Hermannc9bfccc2012-02-08 22:39:30 +0100219 di->decoder->name);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100220 return SRD_ERR_ARG;
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100221 }
222
Uwe Hermann6a155972014-04-13 19:57:43 +0200223 new_channelmap = NULL;
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100224
Uwe Hermann6a155972014-04-13 19:57:43 +0200225 if (!(new_channelmap = g_try_malloc(sizeof(int) * di->dec_num_channels))) {
226 srd_err("Failed to g_malloc() new channel map.");
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100227 return SRD_ERR_MALLOC;
228 }
229
Uwe Hermann38ff5042013-02-02 12:18:29 +0100230 /*
Uwe Hermann6a155972014-04-13 19:57:43 +0200231 * For now, map all indexes to channel -1 (can be overridden later).
232 * This -1 is interpreted as an unspecified channel later.
Uwe Hermann38ff5042013-02-02 12:18:29 +0100233 */
Uwe Hermann6a155972014-04-13 19:57:43 +0200234 for (i = 0; i < di->dec_num_channels; i++)
235 new_channelmap[i] = -1;
Uwe Hermann38ff5042013-02-02 12:18:29 +0100236
Uwe Hermann6a155972014-04-13 19:57:43 +0200237 for (l = g_hash_table_get_keys(new_channels); l; l = l->next) {
238 channel_id = l->data;
239 channel_val = g_hash_table_lookup(new_channels, channel_id);
240 if (!g_variant_is_of_type(channel_val, G_VARIANT_TYPE_INT32)) {
241 /* Channel name was specified without a value. */
242 srd_err("No channel number was specified for %s.",
243 channel_id);
244 g_free(new_channelmap);
Bert Vermeulenbe873262012-01-23 19:34:23 +0100245 return SRD_ERR_ARG;
246 }
Uwe Hermann6a155972014-04-13 19:57:43 +0200247 new_channelnum = g_variant_get_int32(channel_val);
248 if (new_channelnum >= 8 * unit_size) {
249 srd_err("Channel index %d not within data unit (%d bit).",
250 new_channelnum, 8 * unit_size);
251 g_free(new_channelmap);
Daniel Elstner9eec72c2014-02-20 06:24:23 +0100252 return SRD_ERR_ARG;
253 }
Uwe Hermann6a155972014-04-13 19:57:43 +0200254 if (!(sl = g_slist_find_custom(di->decoder->channels, channel_id,
255 (GCompareFunc)compare_channel_id))) {
256 /* Fall back on optional channels. */
257 if (!(sl = g_slist_find_custom(di->decoder->opt_channels,
Uwe Hermannd841d5b2014-08-14 18:51:11 +0200258 channel_id, (GCompareFunc)compare_channel_id))) {
Uwe Hermann6a155972014-04-13 19:57:43 +0200259 srd_err("Protocol decoder %s has no channel "
Uwe Hermannd841d5b2014-08-14 18:51:11 +0200260 "'%s'.", di->decoder->name, channel_id);
Uwe Hermann6a155972014-04-13 19:57:43 +0200261 g_free(new_channelmap);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100262 return SRD_ERR_ARG;
263 }
264 }
Uwe Hermann6a155972014-04-13 19:57:43 +0200265 pdch = sl->data;
266 new_channelmap[pdch->order] = new_channelnum;
267 srd_dbg("Setting channel mapping: %s (index %d) = channel %d.",
268 pdch->id, pdch->order, new_channelnum);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100269 }
Daniel Elstner9eec72c2014-02-20 06:24:23 +0100270 di->data_unitsize = unit_size;
Uwe Hermann38ff5042013-02-02 12:18:29 +0100271
Uwe Hermann6a155972014-04-13 19:57:43 +0200272 srd_dbg("Final channel map:");
273 num_required_channels = g_slist_length(di->decoder->channels);
274 for (i = 0; i < di->dec_num_channels; i++) {
275 srd_dbg(" - index %d = channel %d (%s)", i, new_channelmap[i],
Uwe Hermannd841d5b2014-08-14 18:51:11 +0200276 (i < num_required_channels) ? "required" : "optional");
Uwe Hermann38ff5042013-02-02 12:18:29 +0100277 }
278
Uwe Hermann6a155972014-04-13 19:57:43 +0200279 /* Report an error if not all required channels were specified. */
280 for (i = 0; i < num_required_channels; i++) {
281 if (new_channelmap[i] != -1)
Uwe Hermann9bf7f712014-01-31 00:13:32 +0100282 continue;
Uwe Hermann6a155972014-04-13 19:57:43 +0200283 pdch = g_slist_nth(di->decoder->channels, i)->data;
284 srd_err("Required channel '%s' (index %d) was not specified.",
285 pdch->id, i);
Uwe Hermann9bf7f712014-01-31 00:13:32 +0100286 return SRD_ERR;
287 }
288
Uwe Hermann6a155972014-04-13 19:57:43 +0200289 g_free(di->dec_channelmap);
290 di->dec_channelmap = new_channelmap;
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100291
292 return SRD_OK;
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100293}
294
295/**
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100296 * Create a new protocol decoder instance.
297 *
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200298 * @param sess The session holding the protocol decoder instance.
Uwe Hermann38ff5042013-02-02 12:18:29 +0100299 * @param decoder_id Decoder 'id' field.
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100300 * @param options GHashtable of options which override the defaults set in
Uwe Hermann38ff5042013-02-02 12:18:29 +0100301 * the decoder class. May be NULL.
Bert Vermeulen12243c22012-02-12 14:18:32 +0100302 *
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100303 * @return Pointer to a newly allocated struct srd_decoder_inst, or
Uwe Hermannc9bfccc2012-02-08 22:39:30 +0100304 * NULL in case of failure.
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200305 *
Bert Vermeulen69075812013-10-30 15:22:10 +0100306 * @since 0.3.0
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100307 */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200308SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess,
309 const char *decoder_id, GHashTable *options)
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100310{
Uwe Hermannc9bfccc2012-02-08 22:39:30 +0100311 int i;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100312 struct srd_decoder *dec;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100313 struct srd_decoder_inst *di;
314 char *inst_id;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100315
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100316 srd_dbg("Creating new %s instance.", decoder_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100317
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200318 if (session_is_valid(sess) != SRD_OK) {
319 srd_err("Invalid session.");
320 return NULL;
321 }
322
Bert Vermeulen9d122fd2012-02-14 03:43:28 +0100323 if (!(dec = srd_decoder_get_by_id(decoder_id))) {
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100324 srd_err("Protocol decoder %s not found.", decoder_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100325 return NULL;
326 }
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100327
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100328 if (!(di = g_try_malloc0(sizeof(struct srd_decoder_inst)))) {
Uwe Hermanna61ece22012-02-10 00:06:58 +0100329 srd_err("Failed to g_malloc() instance.");
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100330 return NULL;
331 }
332
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100333 di->decoder = dec;
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200334 di->sess = sess;
Uwe Hermann38ff5042013-02-02 12:18:29 +0100335 if (options) {
336 inst_id = g_hash_table_lookup(options, "id");
337 di->inst_id = g_strdup(inst_id ? inst_id : decoder_id);
338 g_hash_table_remove(options, "id");
339 } else
340 di->inst_id = g_strdup(decoder_id);
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100341
Uwe Hermann361fdca2012-03-15 22:00:24 +0100342 /*
Uwe Hermann6a155972014-04-13 19:57:43 +0200343 * Prepare a default channel map, where samples come in the
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100344 * order in which the decoder class defined them.
345 */
Uwe Hermann6a155972014-04-13 19:57:43 +0200346 di->dec_num_channels = g_slist_length(di->decoder->channels) +
347 g_slist_length(di->decoder->opt_channels);
348 if (di->dec_num_channels) {
349 if (!(di->dec_channelmap =
350 g_try_malloc(sizeof(int) * di->dec_num_channels))) {
351 srd_err("Failed to g_malloc() channel map.");
Bert Vermeulen19a90ba2012-01-21 19:45:04 +0100352 g_free(di);
353 return NULL;
354 }
Uwe Hermann6a155972014-04-13 19:57:43 +0200355 for (i = 0; i < di->dec_num_channels; i++)
356 di->dec_channelmap[i] = i;
357 di->data_unitsize = (di->dec_num_channels + 7) / 8;
Bert Vermeulen37b94c22013-11-26 16:05:54 +0100358 /*
359 * Will be used to prepare a sample at every iteration
360 * of the instance's decode() method.
361 */
Uwe Hermann6a155972014-04-13 19:57:43 +0200362 if (!(di->channel_samples = g_try_malloc(di->dec_num_channels))) {
Bert Vermeulen37b94c22013-11-26 16:05:54 +0100363 srd_err("Failed to g_malloc() sample buffer.");
Uwe Hermann6a155972014-04-13 19:57:43 +0200364 g_free(di->dec_channelmap);
Bert Vermeulen37b94c22013-11-26 16:05:54 +0100365 g_free(di);
366 return NULL;
367 }
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100368 }
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100369
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100370 /* Create a new instance of this decoder class. */
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100371 if (!(di->py_inst = PyObject_CallObject(dec->py_dec, NULL))) {
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100372 if (PyErr_Occurred())
Uwe Hermannaafeeae2012-03-25 15:08:16 +0200373 srd_exception_catch("failed to create %s instance: ",
Bert Vermeulen69075812013-10-30 15:22:10 +0100374 decoder_id);
Uwe Hermann6a155972014-04-13 19:57:43 +0200375 g_free(di->dec_channelmap);
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100376 g_free(di);
377 return NULL;
378 }
379
Uwe Hermann38ff5042013-02-02 12:18:29 +0100380 if (options && srd_inst_option_set(di, options) != SRD_OK) {
Uwe Hermann6a155972014-04-13 19:57:43 +0200381 g_free(di->dec_channelmap);
Bert Vermeulen0bdadba2012-01-17 03:37:34 +0100382 g_free(di);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100383 return NULL;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100384 }
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100385
386 /* Instance takes input from a frontend by default. */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200387 sess->di_list = g_slist_append(sess->di_list, di);
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100388
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100389 return di;
390}
391
Bert Vermeulen582c8472012-02-12 14:55:20 +0100392/**
393 * Stack a decoder instance on top of another.
394 *
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200395 * @param sess The session holding the protocol decoder instances.
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100396 * @param di_bottom The instance on top of which di_top will be stacked.
397 * @param di_top The instance to go on top.
Bert Vermeulen582c8472012-02-12 14:55:20 +0100398 *
399 * @return SRD_OK upon success, a (negative) error code otherwise.
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200400 *
Bert Vermeulen69075812013-10-30 15:22:10 +0100401 * @since 0.3.0
Bert Vermeulen582c8472012-02-12 14:55:20 +0100402 */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200403SRD_API int srd_inst_stack(struct srd_session *sess,
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100404 struct srd_decoder_inst *di_bottom,
405 struct srd_decoder_inst *di_top)
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100406{
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200407
408 if (session_is_valid(sess) != SRD_OK) {
409 srd_err("Invalid session.");
410 return SRD_ERR_ARG;
411 }
412
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100413 if (!di_bottom || !di_top) {
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100414 srd_err("Invalid from/to instance pair.");
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100415 return SRD_ERR_ARG;
416 }
417
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100418 if (g_slist_find(sess->di_list, di_top)) {
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100419 /* Remove from the unstacked list. */
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100420 sess->di_list = g_slist_remove(sess->di_list, di_top);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100421 }
422
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100423 /* Stack on top of source di. */
Bert Vermeulen4d2c7612013-12-10 02:38:44 +0100424 di_bottom->next_di = g_slist_append(di_bottom->next_di, di_top);
425
Uwe Hermannd841d5b2014-08-14 18:51:11 +0200426 srd_dbg("Stacked %s onto %s.", di_top->inst_id, di_bottom->inst_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100427
428 return SRD_OK;
429}
430
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100431/**
Uwe Hermann361fdca2012-03-15 22:00:24 +0100432 * Find a decoder instance by its instance ID.
433 *
434 * Only the bottom level of instances are searched -- instances already stacked
435 * on top of another one will not be found.
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100436 *
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200437 * @param sess The session holding the protocol decoder instance.
Uwe Hermanned2306a2012-03-18 14:16:50 +0100438 * @param inst_id The instance ID to be found.
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100439 *
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100440 * @return Pointer to struct srd_decoder_inst, or NULL if not found.
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200441 *
Bert Vermeulen69075812013-10-30 15:22:10 +0100442 * @since 0.3.0
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100443 */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200444SRD_API struct srd_decoder_inst *srd_inst_find_by_id(struct srd_session *sess,
445 const char *inst_id)
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100446{
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100447 GSList *l;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100448 struct srd_decoder_inst *tmp, *di;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100449
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200450 if (session_is_valid(sess) != SRD_OK) {
451 srd_err("Invalid session.");
452 return NULL;
453 }
454
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100455 di = NULL;
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200456 for (l = sess->di_list; l; l = l->next) {
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100457 tmp = l->data;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100458 if (!strcmp(tmp->inst_id, inst_id)) {
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100459 di = tmp;
460 break;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100461 }
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100462 }
463
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100464 return di;
465}
466
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200467static struct srd_decoder_inst *srd_sess_inst_find_by_obj(
468 struct srd_session *sess, const GSList *stack,
469 const PyObject *obj)
470{
471 const GSList *l;
472 struct srd_decoder_inst *tmp, *di;
473
474 if (session_is_valid(sess) != SRD_OK) {
475 srd_err("Invalid session.");
476 return NULL;
477 }
478
479 di = NULL;
480 for (l = stack ? stack : sess->di_list; di == NULL && l != NULL; l = l->next) {
481 tmp = l->data;
482 if (tmp->py_inst == obj)
483 di = tmp;
484 else if (tmp->next_di)
485 di = srd_sess_inst_find_by_obj(sess, tmp->next_di, obj);
486 }
487
488 return di;
489}
490
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100491/**
Uwe Hermann361fdca2012-03-15 22:00:24 +0100492 * Find a decoder instance by its Python object.
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100493 *
Uwe Hermann361fdca2012-03-15 22:00:24 +0100494 * I.e. find that instance's instantiation of the sigrokdecode.Decoder class.
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200495 * This will recurse to find the instance anywhere in the stack tree of all
496 * sessions.
Uwe Hermann361fdca2012-03-15 22:00:24 +0100497 *
498 * @param stack Pointer to a GSList of struct srd_decoder_inst, indicating the
499 * stack to search. To start searching at the bottom level of
500 * decoder instances, pass NULL.
Uwe Hermann511e2122012-02-10 09:29:38 +0100501 * @param obj The Python class instantiation.
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100502 *
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100503 * @return Pointer to struct srd_decoder_inst, or NULL if not found.
Uwe Hermann57790bc2013-02-09 21:44:11 +0100504 *
505 * @private
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200506 *
507 * @since 0.1.0
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100508 */
Uwe Hermannabeeed82012-03-16 15:12:54 +0100509SRD_PRIV struct srd_decoder_inst *srd_inst_find_by_obj(const GSList *stack,
Bert Vermeulen0ff2d192013-03-19 01:01:25 +0100510 const PyObject *obj)
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100511{
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200512 struct srd_decoder_inst *di;
513 struct srd_session *sess;
514 GSList *l;
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100515
516 di = NULL;
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200517 for (l = sessions; di == NULL && l != NULL; l = l->next) {
518 sess = l->data;
519 di = srd_sess_inst_find_by_obj(sess, stack, obj);
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100520 }
521
522 return di;
523}
524
Uwe Hermann57790bc2013-02-09 21:44:11 +0100525/** @private */
Bert Vermeulened416492013-10-30 16:30:05 +0100526SRD_PRIV int srd_inst_start(struct srd_decoder_inst *di)
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100527{
Bert Vermeulened416492013-10-30 16:30:05 +0100528 PyObject *py_res;
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100529 GSList *l;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100530 struct srd_decoder_inst *next_di;
Bert Vermeulened416492013-10-30 16:30:05 +0100531 int ret;
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100532
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100533 srd_dbg("Calling start() method on protocol decoder instance %s.",
Bert Vermeulened416492013-10-30 16:30:05 +0100534 di->inst_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100535
Bert Vermeulened416492013-10-30 16:30:05 +0100536 if (!(py_res = PyObject_CallMethod(di->py_inst, "start", NULL))) {
Uwe Hermannaafeeae2012-03-25 15:08:16 +0200537 srd_exception_catch("Protocol decoder instance %s: ",
Bert Vermeulened416492013-10-30 16:30:05 +0100538 di->inst_id);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100539 return SRD_ERR_PYTHON;
540 }
Bert Vermeulenf38ec282012-01-20 22:25:42 +0100541 Py_DecRef(py_res);
Bert Vermeulen7ce77752012-01-10 00:25:16 +0100542
Bert Vermeulened416492013-10-30 16:30:05 +0100543 /* Start all the PDs stacked on top of this one. */
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100544 for (l = di->next_di; l; l = l->next) {
545 next_di = l->data;
Bert Vermeulened416492013-10-30 16:30:05 +0100546 if ((ret = srd_inst_start(next_di)) != SRD_OK)
547 return ret;
Bert Vermeulen2072ae02012-01-25 01:49:35 +0100548 }
549
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100550 return SRD_OK;
551}
552
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100553/**
554 * Run the specified decoder function.
555 *
Bert Vermeulened416492013-10-30 16:30:05 +0100556 * @param di The decoder instance to call. Must not be NULL.
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100557 * @param start_samplenum The starting sample number for the buffer's sample
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100558 * set, relative to the start of capture.
Bert Vermeulened416492013-10-30 16:30:05 +0100559 * @param end_samplenum The ending sample number for the buffer's sample
560 * set, relative to the start of capture.
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100561 * @param inbuf The buffer to decode. Must not be NULL.
562 * @param inbuflen Length of the buffer. Must be > 0.
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100563 *
564 * @return SRD_OK upon success, a (negative) error code otherwise.
Uwe Hermann57790bc2013-02-09 21:44:11 +0100565 *
566 * @private
Uwe Hermann8c664ca2013-05-03 14:45:49 +0200567 *
568 * @since 0.1.0
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100569 */
Bert Vermeulened416492013-10-30 16:30:05 +0100570SRD_PRIV int srd_inst_decode(const struct srd_decoder_inst *di,
571 uint64_t start_samplenum, uint64_t end_samplenum,
572 const uint8_t *inbuf, uint64_t inbuflen)
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100573{
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100574 PyObject *py_res;
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100575 srd_logic *logic;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100576
Uwe Hermann74bb0af2013-10-20 23:09:46 +0200577 srd_dbg("Calling decode() on instance %s with %" PRIu64 " bytes "
578 "starting at sample %" PRIu64 ".", di->inst_id, inbuflen,
579 start_samplenum);
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100580
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100581 /* Return an error upon unusable input. */
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100582 if (!di) {
583 srd_dbg("empty decoder instance");
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100584 return SRD_ERR_ARG;
585 }
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100586 if (!inbuf) {
587 srd_dbg("NULL buffer pointer");
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100588 return SRD_ERR_ARG;
589 }
590 if (inbuflen == 0) {
Uwe Hermann7a1712c2012-01-26 01:15:10 +0100591 srd_dbg("empty buffer");
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100592 return SRD_ERR_ARG;
593 }
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100594
Uwe Hermann361fdca2012-03-15 22:00:24 +0100595 /*
596 * Create new srd_logic object. Each iteration around the PD's loop
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100597 * will fill one sample into this object.
598 */
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100599 logic = PyObject_New(srd_logic, &srd_logic_type);
600 Py_INCREF(logic);
Uwe Hermannabeeed82012-03-16 15:12:54 +0100601 logic->di = (struct srd_decoder_inst *)di;
Bert Vermeulen86528292012-01-15 23:20:39 +0100602 logic->start_samplenum = start_samplenum;
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100603 logic->itercnt = 0;
Uwe Hermannabeeed82012-03-16 15:12:54 +0100604 logic->inbuf = (uint8_t *)inbuf;
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100605 logic->inbuflen = inbuflen;
606 logic->sample = PyList_New(2);
607 Py_INCREF(logic->sample);
608
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100609 Py_IncRef(di->py_inst);
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100610 if (!(py_res = PyObject_CallMethod(di->py_inst, "decode",
Bert Vermeulened416492013-10-30 16:30:05 +0100611 "KKO", start_samplenum, end_samplenum, logic))) {
Uwe Hermannd841d5b2014-08-14 18:51:11 +0200612 srd_exception_catch("Protocol decoder instance %s: ",
613 di->inst_id);
Bert Vermeulen0ff2d192013-03-19 01:01:25 +0100614 return SRD_ERR_PYTHON;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100615 }
Bert Vermeulend906d3f2012-01-22 02:51:49 +0100616 Py_DecRef(py_res);
Bert Vermeulenbc5f5a42012-01-05 03:31:36 +0100617
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100618 return SRD_OK;
619}
620
Uwe Hermann57790bc2013-02-09 21:44:11 +0100621/** @private */
Bert Vermeulen12243c22012-02-12 14:18:32 +0100622SRD_PRIV void srd_inst_free(struct srd_decoder_inst *di)
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100623{
624 GSList *l;
625 struct srd_pd_output *pdo;
626
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100627 srd_dbg("Freeing instance %s", di->inst_id);
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100628
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100629 Py_DecRef(di->py_inst);
630 g_free(di->inst_id);
Uwe Hermann6a155972014-04-13 19:57:43 +0200631 g_free(di->dec_channelmap);
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100632 g_slist_free(di->next_di);
633 for (l = di->pd_output; l; l = l->next) {
634 pdo = l->data;
635 g_free(pdo->proto_id);
636 g_free(pdo);
637 }
638 g_slist_free(di->pd_output);
Bert Vermeulene592ac82013-05-05 17:20:13 +0200639 g_free(di);
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100640}
641
Uwe Hermann57790bc2013-02-09 21:44:11 +0100642/** @private */
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200643SRD_PRIV void srd_inst_free_all(struct srd_session *sess, GSList *stack)
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100644{
645 GSList *l;
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100646 struct srd_decoder_inst *di;
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100647
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200648 if (session_is_valid(sess) != SRD_OK) {
649 srd_err("Invalid session.");
650 return;
651 }
652
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100653 di = NULL;
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200654 for (l = stack ? stack : sess->di_list; di == NULL && l != NULL; l = l->next) {
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100655 di = l->data;
656 if (di->next_di)
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200657 srd_inst_free_all(sess, di->next_di);
Bert Vermeulena8b72b02012-02-11 18:06:56 +0100658 srd_inst_free(di);
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100659 }
660 if (!stack) {
Bert Vermeulen32cfb922013-09-12 23:54:43 +0200661 g_slist_free(sess->di_list);
662 sess->di_list = NULL;
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100663 }
Bert Vermeulenfa12a212012-01-31 23:48:10 +0100664}
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100665
Uwe Hermann48954182013-02-09 22:25:15 +0100666/** @} */