gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taler-mdb] branch master updated: implement process to just show


From: gnunet
Subject: [taler-taler-mdb] branch master updated: implement process to just show QR code for some time
Date: Tue, 10 Dec 2019 15:24:42 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository taler-mdb.

The following commit(s) were added to refs/heads/master by this push:
     new 742ae05  implement process to just show QR code for some time
742ae05 is described below

commit 742ae057b9ad85644a1c6621f92e9b710d416beb
Author: Christian Grothoff <address@hidden>
AuthorDate: Tue Dec 10 15:24:39 2019 +0100

    implement process to just show QR code for some time
---
 configure.ac    |   6 +-
 src/Makefile.am |  12 ++
 src/qr-show.c   | 425 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 442 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 7dd8013..a5c8bb8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -96,9 +96,13 @@ AC_ARG_WITH(qrencode,
 
 AS_IF([test "$qrencode" != 1],
 [
+AM_CONDITIONAL(HAVE_QR, false)
 QR_LIBS=""
 QR_CFLAGS=""
-])
+],
+[AM_CONDITIONAL(HAVE_QR, true)])
+
+
 
 AC_SUBST(QR_CFLAGS)
 AC_SUBST(QR_LIBS)
diff --git a/src/Makefile.am b/src/Makefile.am
index f7daf36..f018f6d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,10 @@
 # This Makefile.am is in the public domain
 bin_PROGRAMS = taler-mdb
 
+if HAVE_QR
+bin_PROGRAMS += qr-show
+endif
+
 if USE_COVERAGE
   AM_CFLAGS = --coverage -O0
   XLIB = -lgcov
@@ -21,6 +25,14 @@ taler_mdb_LDADD = \
   $(XLIB)
 
 
+qr_show_SOURCES = \
+  qr-show.c
+qr_show_LDADD = \
+  -lgnunetutil \
+  @QR_LIBS@ \
+  $(XLIB)
+
+
 if HAVE_LIBCURL
 taler_mdb_LDADD += -lcurl
 else
diff --git a/src/qr-show.c b/src/qr-show.c
new file mode 100644
index 0000000..c96dab1
--- /dev/null
+++ b/src/qr-show.c
@@ -0,0 +1,425 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER 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 General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+* @file qr-show.c
+* @brief shows a QR code on the display for a defined amount of time
+* @author Boss Marco
+* @author Christian Grothoff
+*/
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IP_H
+#include <netinet/ip.h>         /* superset of previous */
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <termios.h>
+#include <nfc/nfc.h>
+#include <microhttpd.h>
+#include <gnunet/gnunet_util_lib.h>
+#include <qrencode.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+/* for adafruit pitft display */
+#include <linux/fb.h>
+
+/**
+ * Disable i18n support.
+ */
+#define _(s) (s)
+
+/**
+ * Handle for the Framebuffer device
+ */
+struct Display
+{
+  /**
+   * File descriptor for the screen
+   */
+  int devicefd;
+
+  /**
+   * File descriptor to set backlight information
+   */
+  int backlightfd;
+
+  /**
+   * The display memory to set the pixel information
+   */
+  uint16_t *memory;
+
+  /**
+   * Original screen information
+   */
+  struct fb_var_screeninfo orig_vinfo;
+
+  /**
+   * Variable screen information (color depth ...)
+   */
+  struct fb_var_screeninfo var_info;
+
+  /**
+   * Fixed screen informtaion
+   */
+  struct fb_fix_screeninfo fix_info;
+};
+
+
+/**
+ * Next program to launch.
+ */
+static char *const *arg_next;
+
+static struct GNUNET_TIME_Relative delay;
+
+/**
+ * Refenence to the delay task
+ */
+static struct GNUNET_SCHEDULER_Task *delay_task;
+
+/**
+ * Name of the framebuffer device (i.e. /dev/fb1).
+ */
+static char *framebuffer_device_filename;
+
+/**
+ * Name of the backlight file of @e framebuffer_device_filename (i.e. 
/sys/class/backlight/soc:backlight/brightness).
+ */
+static char *framebuffer_backlight_filename;
+
+static int backlight_invert;
+static char backlight_on = '1';
+static char backlight_off = '0';
+
+/**
+ * Handle for the framebuffer device
+ */
+static struct Display qrDisplay;
+
+
+/**
+ * @brief Create the QR code to pay and display it on screen
+ *
+ * @param uri what text to show in the QR code
+ */
+static void
+show_qrcode (const char *uri)
+{
+  QRinput *qri;
+  QRcode *qrc;
+  unsigned int size;
+  size_t xOff;
+  size_t yOff;
+
+  if (0 > qrDisplay.devicefd)
+    return; /* no display, no dice */
+  qri = QRinput_new2 (0, QR_ECLEVEL_L);
+  if (NULL == qri)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                         "QRinput_new2");
+    return;
+  }
+  /* first try encoding as uppercase-only alpha-numerical
+     QR code (much smaller encoding); if that fails, also
+     try using binary encoding (in case nick contains
+     special characters). */
+  if ( (0 !=
+        QRinput_append (qri,
+                        QR_MODE_AN,
+                        strlen (uri),
+                        (unsigned char *) uri)) &&
+       (0 !=
+        QRinput_append (qri,
+                        QR_MODE_8,
+                        strlen (uri),
+                        (unsigned char *) uri)))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                         "QRinput_append");
+    return;
+  }
+  qrc = QRcode_encodeInput (qri);
+  if (NULL == qrc)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                         "QRcode_encodeInput");
+    QRinput_free (qri);
+    return;
+  }
+
+  /* +8 for 4-pixels border */
+  size = GNUNET_MIN (qrDisplay.var_info.xres,
+                     qrDisplay.var_info.yres);
+  unsigned int nwidth = qrc->width + 8; /* 4 pixel border */
+  xOff = 4 * size / nwidth;
+  yOff = 4 * size / nwidth;
+  if (qrDisplay.var_info.xres < qrDisplay.var_info.yres)
+    yOff += (qrDisplay.var_info.yres - qrDisplay.var_info.xres) / 2;
+  else
+    xOff += (qrDisplay.var_info.xres - qrDisplay.var_info.yres) / 2;
+  for (unsigned int x = 0; x < qrDisplay.var_info.xres - 2 * xOff; x++)
+    for (unsigned int y = 0; y < qrDisplay.var_info.yres - 2 * yOff; y++)
+    {
+      unsigned int xoff = x * nwidth / size;
+      unsigned int yoff = y * nwidth / size;
+      unsigned int off = xoff + yoff * qrc->width;
+      if ( (xoff >= (unsigned) qrc->width) ||
+           (yoff >= (unsigned) qrc->width) )
+        continue;
+      qrDisplay.memory[(y + yOff) * qrDisplay.var_info.xres + (x + xOff)] =
+        (0 == (qrc->data[off] & 1)) ? 0xFFFF : 0x0000;
+    }
+
+  QRcode_free (qrc);
+  QRinput_free (qri);
+
+  if (0 < qrDisplay.backlightfd)
+    (void) write (qrDisplay.backlightfd, &backlight_on, 1);
+}
+
+
+static void
+stop_task (void *cls)
+{
+  (void) cls;
+  delay_task = NULL;
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
+static void
+shutdown_task (void *cls)
+{
+  (void) cls;
+  if (NULL != delay_task)
+  {
+    GNUNET_SCHEDULER_cancel (delay_task);
+    delay_task = NULL;
+  }
+  if (NULL != qrDisplay.memory)
+    memset (qrDisplay.memory,
+            0xFF,
+            qrDisplay.var_info.xres * qrDisplay.var_info.yres
+            * sizeof (uint16_t));
+  if (0 < qrDisplay.backlightfd)
+    (void) write (qrDisplay.backlightfd, &backlight_off, 1);
+  if (NULL != qrDisplay.memory)
+  {
+    /* free the display data  */
+    munmap (qrDisplay.memory,
+            qrDisplay.fix_info.smem_len);
+    qrDisplay.memory = NULL;
+    /* reset original state */
+    if (0 > ioctl (qrDisplay.devicefd,
+                   FBIOPUT_VSCREENINFO,
+                   &qrDisplay.orig_vinfo))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "failed to reset originial display state\n");
+    }
+    /* close device */
+    close (qrDisplay.devicefd);
+    qrDisplay.devicefd = -1;
+    if (0 < qrDisplay.backlightfd)
+      close (qrDisplay.backlightfd);
+    qrDisplay.backlightfd = -1;
+  }
+}
+
+
+/**
+ * @brief Start the application
+ *
+ * @param cls closure
+ * @param args arguments left
+ * @param cfgfile config file name
+ * @param cfg handle for the configuation file
+ */
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  (void) cls;
+  (void) cfgfile;
+
+  if (NULL == args[0])
+    return;
+  arg_next = args + 1;
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_filename (cfg,
+                                               "taler-mdb",
+                                               "FRAMEBUFFER_DEVICE",
+                                               &framebuffer_device_filename))
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                               "taler-mdb",
+                               "FRAMEBUFFER_DEVICE");
+    framebuffer_device_filename = GNUNET_strdup ("/dev/fb1");
+  }
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_filename (cfg,
+                                               "taler-mdb",
+                                               "FRAMEBUFFER_BACKLIGHT",
+                                               
&framebuffer_backlight_filename))
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                               "taler-mdb",
+                               "FRAMEBUFFER_BACKLIGHT");
+    framebuffer_backlight_filename = GNUNET_strdup (
+      "/sys/class/backlight/soc:backlight/brightness");
+  }
+  /* open the framebuffer device */
+  qrDisplay.devicefd = open (framebuffer_device_filename,
+                             O_RDWR);
+  if (0 < qrDisplay.devicefd)
+  {
+    /* read information about the screen */
+    ioctl (qrDisplay.devicefd,
+           FBIOGET_VSCREENINFO,
+           &qrDisplay.var_info);
+
+    /* store current screeninfo for reset */
+    qrDisplay.orig_vinfo = qrDisplay.var_info;
+
+    if (16 != qrDisplay.var_info.bits_per_pixel)
+    {
+      /* Change variable info to 16 bit per pixel */
+      qrDisplay.var_info.bits_per_pixel = 16;
+      if (0 > ioctl (qrDisplay.devicefd,
+                     FBIOPUT_VSCREENINFO,
+                     &qrDisplay.var_info))
+      {
+        GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                             "ioctl(FBIOPUT_VSCREENINFO)");
+        return;
+      }
+    }
+
+    /* Get fixed screen information */
+    if (0 > ioctl (qrDisplay.devicefd,
+                   FBIOGET_FSCREENINFO,
+                   &qrDisplay.fix_info))
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                           "ioctl(FBIOGET_FSCREENINFO)");
+      return;
+    }
+
+    /* get pointer onto frame buffer */
+    qrDisplay.memory =  mmap (NULL,
+                              qrDisplay.fix_info.smem_len,
+                              PROT_READ | PROT_WRITE, MAP_SHARED,
+                              qrDisplay.devicefd,
+                              0);
+
+    /* open backlight file to turn display backlight on and off */
+    if (0 > qrDisplay.devicefd)
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                           "mmap");
+      return;
+    }
+
+    memset (qrDisplay.memory,
+            0xFF,
+            qrDisplay.var_info.xres * qrDisplay.var_info.yres
+            * sizeof (uint16_t));
+
+    qrDisplay.backlightfd = open (
+      framebuffer_backlight_filename, O_WRONLY);
+    if (0 > qrDisplay.backlightfd)
+    {
+      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                                "open",
+                                framebuffer_backlight_filename);
+    }
+    else
+    {
+      if (backlight_invert)
+      {
+        backlight_on = '0';
+        backlight_off = '1';
+      }
+      (void) write (qrDisplay.backlightfd, &backlight_off, 1);
+    }
+  }
+  else
+  {
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                              "open",
+                              framebuffer_device_filename);
+  }
+  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+                                 NULL);
+  show_qrcode (args[0]);
+  delay_task = GNUNET_SCHEDULER_add_delayed (delay,
+                                             &stop_task,
+                                             NULL);
+}
+
+
+int
+main (int argc,
+      char*const*argv)
+{
+  int ret;
+  /* the available command line options */
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_option_relative_time ('d',
+                                        "delay",
+                                        "DELAY",
+                                        "how long should we display the text 
before continuing",
+                                        &delay),
+    GNUNET_GETOPT_OPTION_END
+  };
+
+  ret = GNUNET_PROGRAM_run (argc,
+                            argv,
+                            "qr-show",
+                            "This is an application to show a QR code for a 
defined period of time before starting another program.\n",
+                            options,
+                            &run,
+                            NULL);
+  if (GNUNET_OK != ret)
+    return 1;
+  if ( (NULL == arg_next) ||
+       (NULL == arg_next[0]) )
+    return 0;
+  execvp (arg_next[0],
+          arg_next);
+  GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+                            "execvp",
+                            arg_next[0]);
+  return 1;
+}

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]