]> sigrok.org Git - libsigrokdecode.git/blobdiff - controller.c
Main header is <libsigrokdecode/libsigrokdecode.h> now.
[libsigrokdecode.git] / controller.c
index 44fd6c76e079359e5a9af4a810bc249a4130385c..c9825b95cfc70c8fd6448f9001e851bd6957be3b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * This file is part of the sigrok project.
+ * This file is part of the libsigrokdecode project.
  *
  * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
  * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
@@ -18,8 +18,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "sigrokdecode.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
-#include "sigrokdecode-internal.h"
+#include "libsigrokdecode.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
+#include "libsigrokdecode-internal.h"
 #include "config.h"
 #include <glib.h>
 #include <inttypes.h>
@@ -130,6 +130,8 @@ extern SRD_PRIV PyTypeObject srd_logic_type;
  *         Upon Python errors, return SRD_ERR_PYTHON. If the sigrok decoders
  *         directory cannot be accessed, return SRD_ERR_DECODERS_DIR.
  *         If not enough memory could be allocated, return SRD_ERR_MALLOC.
+ *
+ * @since 0.1.0
  */
 SRD_API int srd_init(const char *path)
 {
@@ -180,6 +182,8 @@ SRD_API int srd_init(const char *path)
  * any successful srd_init() calls in between, is not allowed.
  *
  * @return SRD_OK upon success, a (negative) error code otherwise.
+ *
+ * @since 0.1.0
  */
 SRD_API int srd_exit(void)
 {
@@ -211,6 +215,8 @@ SRD_API int srd_exit(void)
  * @return SRD_OK upon success, a (negative) error code otherwise.
  *
  * @private
+ *
+ * @since 0.1.0
  */
 SRD_PRIV int srd_decoder_searchpath_add(const char *path)
 {
@@ -265,6 +271,16 @@ SRD_PRIV int srd_decoder_searchpath_add(const char *path)
        return SRD_OK;
 }
 
+/** @} */
+
+/**
+ * @defgroup grp_instances Decoder instances
+ *
+ * Decoder instance handling.
+ *
+ * @{
+ */
+
 /**
  * Set one or more options in a decoder instance.
  *
@@ -274,16 +290,21 @@ SRD_PRIV int srd_decoder_searchpath_add(const char *path)
  * @param options A GHashTable of options to set.
  *
  * @return SRD_OK upon success, a (negative) error code otherwise.
+ *
+ * @since 0.1.0
  */
 SRD_API int srd_inst_option_set(struct srd_decoder_inst *di,
-                               GHashTable *options)
+               GHashTable *options)
 {
        PyObject *py_dec_options, *py_dec_optkeys, *py_di_options, *py_optval;
        PyObject *py_optlist, *py_classval;
        Py_UNICODE *py_ustr;
+       GVariant *value;
        unsigned long long int val_ull;
+       gint64 val_int;
        int num_optkeys, ret, size, i;
-       char *key, *value;
+       const char *val_str;
+       char *dbg, *key;
 
        if (!PyObject_HasAttrString(di->decoder->py_dec, "options")) {
                /* Decoder has no options. */
@@ -322,20 +343,32 @@ SRD_API int srd_inst_option_set(struct srd_decoder_inst *di,
                }
 
                if ((value = g_hash_table_lookup(options, key))) {
+                       dbg = g_variant_print(value, TRUE);
+                       srd_dbg("got option '%s' = %s", key, dbg);
+                       g_free(dbg);
                        /* An override for this option was provided. */
                        if (PyUnicode_Check(py_classval)) {
-                               if (!(py_optval = PyUnicode_FromString(value))) {
+                               if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                                       srd_err("Option '%s' requires a string value.", key);
+                                       goto err_out;
+                               }
+                               val_str = g_variant_get_string(value, NULL);
+                               if (!(py_optval = PyUnicode_FromString(val_str))) {
                                        /* Some UTF-8 encoding error. */
                                        PyErr_Clear();
+                                       srd_err("Option '%s' requires a UTF-8 string value.", key);
                                        goto err_out;
                                }
                        } else if (PyLong_Check(py_classval)) {
-                               if (!(py_optval = PyLong_FromString(value, NULL, 0))) {
+                               if (!g_variant_is_of_type(value, G_VARIANT_TYPE_INT64)) {
+                                       srd_err("Option '%s' requires an integer value.", key);
+                                       goto err_out;
+                               }
+                               val_int = g_variant_get_int64(value);
+                               if (!(py_optval = PyLong_FromLong(val_int))) {
                                        /* ValueError Exception */
                                        PyErr_Clear();
-                                       srd_err("Option %s has invalid value "
-                                               "%s: expected integer.",
-                                               key, value);
+                                       srd_err("Option '%s' has invalid integer value.", key);
                                        goto err_out;
                                }
                        }
@@ -402,15 +435,18 @@ static gint compare_probe_id(const struct srd_probe *a, const char *probe_id)
  *                   arranged in this order.
  *
  * @return SRD_OK upon success, a (negative) error code otherwise.
+ *
+ * @since 0.1.0
  */
 SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di,
-                                  GHashTable *new_probes)
+               GHashTable *new_probes)
 {
+       GVariant *probe_val;
        GList *l;
        GSList *sl;
        struct srd_probe *p;
        int *new_probemap, new_probenum;
-       char *probe_id, *probenum_str;
+       char *probe_id;
        int i, num_required_probes;
 
        srd_dbg("set probes called for instance %s with list of %d probes",
@@ -443,22 +479,22 @@ SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di,
 
        for (l = g_hash_table_get_keys(new_probes); l; l = l->next) {
                probe_id = l->data;
-               probenum_str = g_hash_table_lookup(new_probes, probe_id);
-               if (!probenum_str) {
+               probe_val= g_hash_table_lookup(new_probes, probe_id);
+               if (!g_variant_is_of_type(probe_val, G_VARIANT_TYPE_INT32)) {
                        /* Probe name was specified without a value. */
                        srd_err("No probe number was specified for %s.",
-                               probe_id);
+                                       probe_id);
                        g_free(new_probemap);
                        return SRD_ERR_ARG;
                }
-               new_probenum = strtol(probenum_str, NULL, 10);
+               new_probenum = g_variant_get_int32(probe_val);
                if (!(sl = g_slist_find_custom(di->decoder->probes, probe_id,
                                (GCompareFunc)compare_probe_id))) {
                        /* Fall back on optional probes. */
                        if (!(sl = g_slist_find_custom(di->decoder->opt_probes,
                             probe_id, (GCompareFunc) compare_probe_id))) {
                                srd_err("Protocol decoder %s has no probe "
-                                       "'%s'.", di->decoder->name, probe_id);
+                                               "'%s'.", di->decoder->name, probe_id);
                                g_free(new_probemap);
                                return SRD_ERR_ARG;
                        }
@@ -491,9 +527,11 @@ SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di,
  *
  * @return Pointer to a newly allocated struct srd_decoder_inst, or
  *         NULL in case of failure.
+ *
+ * @since 0.1.0
  */
 SRD_API struct srd_decoder_inst *srd_inst_new(const char *decoder_id,
-                                             GHashTable *options)
+               GHashTable *options)
 {
        int i;
        struct srd_decoder *dec;
@@ -566,9 +604,11 @@ SRD_API struct srd_decoder_inst *srd_inst_new(const char *decoder_id,
  * @param di_to The instance on top of which di_from will be stacked.
  *
  * @return SRD_OK upon success, a (negative) error code otherwise.
+ *
+ * @since 0.1.0
  */
 SRD_API int srd_inst_stack(struct srd_decoder_inst *di_from,
-                          struct srd_decoder_inst *di_to)
+               struct srd_decoder_inst *di_to)
 {
        if (!di_from || !di_to) {
                srd_err("Invalid from/to instance pair.");
@@ -595,6 +635,8 @@ SRD_API int srd_inst_stack(struct srd_decoder_inst *di_from,
  * @param inst_id The instance ID to be found.
  *
  * @return Pointer to struct srd_decoder_inst, or NULL if not found.
+ *
+ * @since 0.1.0
  */
 SRD_API struct srd_decoder_inst *srd_inst_find_by_id(const char *inst_id)
 {
@@ -627,11 +669,12 @@ SRD_API struct srd_decoder_inst *srd_inst_find_by_id(const char *inst_id)
  * @return Pointer to struct srd_decoder_inst, or NULL if not found.
  *
  * @private
+ *
+ * @since 0.1.0
  */
 SRD_PRIV struct srd_decoder_inst *srd_inst_find_by_obj(const GSList *stack,
-                                                      const PyObject *obj)
+               const PyObject *obj)
 {
-// TODO?
        const GSList *l;
        struct srd_decoder_inst *tmp, *di;
 
@@ -699,10 +742,12 @@ SRD_PRIV int srd_inst_start(struct srd_decoder_inst *di, PyObject *args)
  * @return SRD_OK upon success, a (negative) error code otherwise.
  *
  * @private
+ *
+ * @since 0.1.0
  */
 SRD_PRIV int srd_inst_decode(uint64_t start_samplenum,
-                            const struct srd_decoder_inst *di,
-                            const uint8_t *inbuf, uint64_t inbuflen)
+               const struct srd_decoder_inst *di, const uint8_t *inbuf,
+               uint64_t inbuflen)
 {
        PyObject *py_res;
        srd_logic *logic;
@@ -746,7 +791,7 @@ SRD_PRIV int srd_inst_decode(uint64_t start_samplenum,
                                           end_samplenum, logic))) {
                srd_exception_catch("Protocol decoder instance %s: ",
                                    di->inst_id);
-               return SRD_ERR_PYTHON; /* TODO: More specific error? */
+               return SRD_ERR_PYTHON;
        }
        Py_DecRef(py_res);
 
@@ -792,6 +837,16 @@ SRD_PRIV void srd_inst_free_all(GSList *stack)
        }
 }
 
+/** @} */
+
+/**
+ * @defgroup grp_session Session handling
+ *
+ * Starting and handling decoding sessions.
+ *
+ * @{
+ */
+
 /**
  * Start a decoding session.
  *
@@ -802,6 +857,8 @@ SRD_PRIV void srd_inst_free_all(GSList *stack)
  * @param samplerate The samplerate of the incoming feed.
  *
  * @return SRD_OK upon success, a (negative) error code otherwise.
+ *
+ * @since 0.1.0
  */
 SRD_API int srd_session_start(int num_probes, int unitsize, uint64_t samplerate)
 {
@@ -847,9 +904,11 @@ SRD_API int srd_session_start(int num_probes, int unitsize, uint64_t samplerate)
  * @param inbuflen Length in bytes of the buffer.
  *
  * @return SRD_OK upon success, a (negative) error code otherwise.
+ *
+ * @since 0.1.0
  */
 SRD_API int srd_session_send(uint64_t start_samplenum, const uint8_t *inbuf,
-                            uint64_t inbuflen)
+               uint64_t inbuflen)
 {
        GSList *d;
        int ret;
@@ -878,9 +937,11 @@ SRD_API int srd_session_send(uint64_t start_samplenum, const uint8_t *inbuf,
  *                    callback per output type can be registered.
  * @param cb The function to call. Must not be NULL.
  * @param cb_data Private data for the callback function. Can be NULL.
+ *
+ * @since 0.1.0
  */
 SRD_API int srd_pd_output_callback_add(int output_type,
-                               srd_pd_output_callback_t cb, void *cb_data)
+               srd_pd_output_callback_t cb, void *cb_data)
 {
        struct srd_pd_callback *pd_cb;