summaryrefslogtreecommitdiffstats
path: root/test/test_dbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_dbus.c')
-rw-r--r--test/test_dbus.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/test/test_dbus.c b/test/test_dbus.c
new file mode 100644
index 0000000..60a415e
--- /dev/null
+++ b/test/test_dbus.c
@@ -0,0 +1,254 @@
+/*------------------------------------------------------------------------
+ * Copyright 2019 (c) Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+ *
+ * This file is part of the ZBar Bar Code Reader.
+ *
+ * The ZBar Bar Code Reader is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The ZBar Bar Code Reader is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser Public License for more details.
+ *------------------------------------------------------------------------*/
+
+#include <argp.h>
+#include <dbus/dbus.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define ZBAR_INTERFACE "org.linuxtv.Zbar1.Code"
+#define ZBAR_SIGNAL_CODE "Code"
+#define ZBAR_SIGNAL_TYPE "Type"
+#define ZBAR_SIGNAL_DATA "Data"
+#define ZBAR_SIGNAL_BINARY_DATA "BinaryData"
+
+#define PROGRAM_NAME "test_dbus"
+
+static const char doc[] = "\nTest if ZBar is sending codes via D-Bus\n";
+
+static const struct argp_option options[] = {
+ { "count", 'c', "#codes", 0, "Stop after received #codes", 0 },
+ { "time", 't', "#seconds", 0, "Stop after #seconds", 0 },
+ { "log", 'l', "#file", 0, "Write log to #file", 0 },
+ { "bin-log", 'b', "#file", 0, "Write binary log to #file", 0 },
+ { "help", '?', 0, 0, "Give this help list", -1 },
+ { "usage", -3, 0, 0, "Give a short usage message", 0 },
+ { 0 }
+};
+
+static int max_msg = 0;
+static int timeout = 0;
+static FILE *log = NULL;
+static FILE *bin_log = NULL;
+
+static error_t parse_opt(int k, char *optarg, struct argp_state *state)
+{
+ switch (k) {
+ case 'c':
+ max_msg = strtoul(optarg, NULL, 0);
+ break;
+ case 't':
+ timeout = strtoul(optarg, NULL, 0);
+ break;
+ case 'l':
+ log = fopen(optarg, "wb");
+ break;
+ case 'b':
+ bin_log = fopen(optarg, "wb");
+ break;
+ case '?':
+ argp_state_help(state, state->out_stream,
+ ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_DOC);
+ exit(0);
+ case -3:
+ argp_state_help(state, state->out_stream, ARGP_HELP_USAGE);
+ exit(0);
+ default:
+ return ARGP_ERR_UNKNOWN;
+ };
+ return 0;
+}
+
+static const struct argp argp = {
+ .options = options,
+ .parser = parse_opt,
+ .doc = doc,
+};
+
+int main(int argc, char *argv[])
+{
+ DBusMessage *msg;
+ DBusMessageIter args, entry, dict, val;
+ DBusConnection *conn;
+ DBusError err;
+ char *str, *property;
+ int count = 0, length = 0;
+
+ if (argp_parse(&argp, argc, argv, ARGP_NO_HELP | ARGP_NO_EXIT, 0, 0)) {
+ argp_help(&argp, stderr, ARGP_HELP_SHORT_USAGE, PROGRAM_NAME);
+ return -1;
+ }
+
+ if (!log)
+ log = fdopen(dup(fileno(stderr)), "w+");
+
+ if (!bin_log)
+ bin_log = fdopen(dup(fileno(stderr)), "w+");
+
+ // initialise the error value
+ dbus_error_init(&err);
+
+ // connect to the DBUS system bus, and check for errors
+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+ if (dbus_error_is_set(&err)) {
+ fprintf(stderr, "Connection Error (%s)\n", err.message);
+ dbus_error_free(&err);
+ }
+ if (!conn) {
+ fprintf(stderr, "Connection Null\n");
+ return -1;
+ }
+
+ dbus_bus_add_match(conn, "type='signal',interface='" ZBAR_INTERFACE "'",
+ &err);
+ dbus_connection_flush(conn);
+ if (dbus_error_is_set(&err)) {
+ fprintf(stderr, "Match Error (%s)\n", err.message);
+ exit(1);
+ }
+
+ if (timeout)
+ alarm(timeout);
+
+ /* loop listening for signals being emitted */
+ fprintf(stderr, "Waiting for Zbar events\n");
+ while (true) {
+ // non blocking read of the next available message
+ dbus_connection_read_write(conn, 0);
+ msg = dbus_connection_pop_message(conn);
+
+ // loop again if we haven't read a message
+ if (NULL == msg) {
+ sleep(1);
+ continue;
+ }
+
+ // check if the message is a signal from the correct interface and with the
+ // correct name
+ if (dbus_message_is_signal(msg, ZBAR_INTERFACE, ZBAR_SIGNAL_CODE)) {
+ // read the parameters
+ if (!dbus_message_iter_init(msg, &args))
+ fprintf(stderr, "Message has no arguments!\n");
+ else if (DBUS_TYPE_ARRAY != dbus_message_iter_get_arg_type(&args))
+ fprintf(stderr, "Argument is not array!\n");
+ else {
+ while (dbus_message_iter_get_arg_type(&args) !=
+ DBUS_TYPE_INVALID) {
+ dbus_message_iter_recurse(&args, &entry);
+ if (DBUS_TYPE_DICT_ENTRY !=
+ dbus_message_iter_get_arg_type(&entry)) {
+ fprintf(stderr, "Element is not dict entry!\n");
+ } else {
+ while (dbus_message_iter_get_arg_type(&entry) !=
+ DBUS_TYPE_INVALID) {
+ dbus_message_iter_recurse(&entry, &dict);
+ if (DBUS_TYPE_STRING !=
+ dbus_message_iter_get_arg_type(&dict)) {
+ fprintf(stderr,
+ "Dict Entry key is not string!\n");
+ } else {
+ dbus_message_iter_get_basic(&dict, &property);
+ dbus_message_iter_next(&dict);
+ if (DBUS_TYPE_VARIANT !=
+ dbus_message_iter_get_arg_type(&dict)) {
+ fprintf(
+ stderr,
+ "Dict Entry value is not variant!\n");
+ } else {
+ dbus_message_iter_recurse(&dict, &val);
+ if (strcmp(property, ZBAR_SIGNAL_TYPE) ==
+ 0) {
+ if (DBUS_TYPE_STRING !=
+ dbus_message_iter_get_arg_type(
+ &val)) {
+ fprintf(
+ stderr,
+ "Dict Entry value for barcode type is not string!\n");
+ } else {
+ dbus_message_iter_get_basic(&val,
+ &str);
+ fprintf(stderr, "Type = %s\n", str);
+ }
+ } else if (strcmp(property,
+ ZBAR_SIGNAL_DATA) == 0) {
+ if (DBUS_TYPE_STRING !=
+ dbus_message_iter_get_arg_type(
+ &val)) {
+ fprintf(
+ stderr,
+ "Dict Entry value for barcode text data is not string!\n");
+ } else {
+ dbus_message_iter_get_basic(&val,
+ &str);
+ fprintf(stderr, "Value = %s\n",
+ str);
+ fprintf(log, "%s\n", str);
+ }
+ } else if (strcmp(property,
+ ZBAR_SIGNAL_BINARY_DATA) ==
+ 0) {
+ if (DBUS_TYPE_ARRAY !=
+ dbus_message_iter_get_arg_type(
+ &val)) {
+ fprintf(
+ stderr,
+ "Dict Entry value for barcode binary data is not array!\n");
+ } else {
+ dbus_message_iter_recurse(&val,
+ &val);
+ if (DBUS_TYPE_BYTE !=
+ dbus_message_iter_get_arg_type(
+ &val)) {
+ fprintf(
+ stderr,
+ "Dict Entry value for barcode binary data is not array of bytes!\n");
+ } else {
+ dbus_message_iter_get_fixed_array(
+ &val, &str, &length);
+ fprintf(stderr,
+ "BinaryData[%d]\n",
+ length);
+ fwrite(str, sizeof(*str),
+ length, bin_log);
+ }
+ }
+ }
+ }
+ }
+ dbus_message_iter_next(&entry);
+ }
+ /* If max_msg > 0, stops after receiving 'count' messages */
+ if (++count == max_msg) {
+ dbus_message_unref(msg);
+ return 0;
+ }
+ }
+ dbus_message_iter_next(&args);
+ }
+ }
+ }
+ // free the message
+ dbus_message_unref(msg);
+ }
+
+ fclose(log);
+ fclose(bin_log);
+
+ return 0;
+}