LCOV - code coverage report
Current view: top level - examples - notificationAsync.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 71 0.0 %
Date: 2019-09-12 12:28:41 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief Example for notification library which repeatedly reads some keys and
       5             :  * reacts to them
       6             :  *
       7             :  * Requires:
       8             :  *   - io_uv binding
       9             :  *   - Transport plugins (e.g. kdb global-mount dbus announce=once dbusrecv)
      10             :  *
      11             :  * Relevant keys for this example:
      12             :  *   - /sw/example/notification/#0/current/value: Set to any integer value
      13             :  *   - /sw/example/notification/#0/current/color: Set the text color. Possible
      14             :  *     values are "red", "green" and "blue".
      15             :  *
      16             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
      17             :  *
      18             :  */
      19             : 
      20             : #include <kdb.h>
      21             : #include <kdbhelper.h>       // elektraFree
      22             : #include <kdbio.h>           // I/O binding functions (elektraIo*)
      23             : #include <kdbio/uv.h>     // I/O binding constructor for uv (elektraIoUvNew)
      24             : #include <kdbnotification.h> // notification functions
      25             : 
      26             : #include <uv.h> // uv functions
      27             : 
      28             : #include <signal.h> // signal()
      29             : #include <stdio.h>  // printf() & co
      30             : 
      31             : uv_async_t wakeup;
      32             : 
      33             : #ifdef HAVE_LIBUV0
      34             : static void wakeupCallback (uv_async_t * async ELEKTRA_UNUSED, int unknown ELEKTRA_UNUSED)
      35             : {
      36             :         // nothing to do; callback required for libuv 0.x
      37             : }
      38             : #endif
      39             : 
      40             : // from https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
      41             : #define ANSI_COLOR_RESET "\x1b[0m"
      42             : #define ANSI_COLOR_RED "\x1b[31m"
      43             : #define ANSI_COLOR_GREEN "\x1b[32m"
      44             : #define ANSI_COLOR_BLUE "\x1b[34m"
      45             : 
      46           0 : static void setTerminalColor (Key * color, void * context ELEKTRA_UNUSED)
      47             : {
      48           0 :         const char * value = keyString (color);
      49           0 :         printf ("Callback called. Changing color to %s\n", value);
      50             : 
      51           0 :         if (elektraStrCmp (value, "red") == 0)
      52             :         {
      53           0 :                 printf (ANSI_COLOR_RED);
      54             :         }
      55           0 :         else if (elektraStrCmp (value, "green") == 0)
      56             :         {
      57           0 :                 printf (ANSI_COLOR_GREEN);
      58             :         }
      59           0 :         else if (elektraStrCmp (value, "blue") == 0)
      60             :         {
      61           0 :                 printf (ANSI_COLOR_BLUE);
      62             :         }
      63             :         else
      64             :         {
      65           0 :                 printf ("Specified color (%s) did not match \"red\", \"green\" or \"blue\". Using default color.\n", value);
      66           0 :                 printf (ANSI_COLOR_RESET);
      67             :         }
      68           0 : }
      69             : 
      70             : static void resetTerminalColor (void)
      71             : {
      72           0 :         printf (ANSI_COLOR_RESET "\n");
      73             : }
      74             : 
      75           0 : static void onSIGNAL (int signal)
      76             : {
      77           0 :         if (signal == SIGINT)
      78             :         {
      79           0 :                 uv_stop (uv_default_loop ());
      80             :                 // Without this call the loop would be "sleeping" until the next timer interval
      81           0 :                 uv_async_send (&wakeup);
      82             :         }
      83           0 : }
      84             : 
      85           0 : static void printVariable (ElektraIoTimerOperation * timerOp)
      86             : {
      87           0 :         int value = *(int *) elektraIoTimerGetData (timerOp);
      88           0 :         printf ("\nMy integer value is %d\n", value);
      89           0 : }
      90             : 
      91           0 : int main (void)
      92             : {
      93             :         // Cleanup on SIGINT
      94           0 :         signal (SIGINT, onSIGNAL);
      95             : 
      96           0 :         KeySet * config = ksNew (20, KS_END);
      97             : 
      98           0 :         Key * key = keyNew ("/sw/example/notification/#0/current", KEY_END);
      99           0 :         KDB * kdb = kdbOpen (key);
     100           0 :         if (kdb == NULL)
     101             :         {
     102           0 :                 printf ("could not open KDB, aborting\n");
     103           0 :                 return -1;
     104             :         }
     105             : 
     106           0 :         uv_loop_t * loop = uv_default_loop ();
     107           0 :         ElektraIoInterface * binding = elektraIoUvNew (loop);
     108           0 :         elektraIoSetBinding (kdb, binding);
     109             : 
     110           0 :         int result = elektraNotificationOpen (kdb);
     111           0 :         if (!result)
     112             :         {
     113           0 :                 printf ("could not init notification, aborting\n");
     114           0 :                 return -1;
     115             :         }
     116             : 
     117           0 :         int value = 0;
     118           0 :         Key * intKeyToWatch = keyNew ("/sw/example/notification/#0/current/value", KEY_END);
     119           0 :         result = elektraNotificationRegisterInt (kdb, intKeyToWatch, &value);
     120           0 :         if (!result)
     121             :         {
     122           0 :                 printf ("could not register variable, aborting\n");
     123           0 :                 return -1;
     124             :         }
     125             : 
     126           0 :         Key * callbackKeyToWatch = keyNew ("/sw/example/notification/#0/current/color", KEY_END);
     127           0 :         result = elektraNotificationRegisterCallback (kdb, callbackKeyToWatch, &setTerminalColor, NULL);
     128           0 :         if (!result)
     129             :         {
     130           0 :                 printf ("could not register callback, aborting!");
     131           0 :                 return -1;
     132             :         }
     133             : 
     134             :         // Setup timer that repeatedly prints the variable
     135           0 :         ElektraIoTimerOperation * timer = elektraIoNewTimerOperation (2000, 1, printVariable, &value);
     136           0 :         elektraIoBindingAddTimer (binding, timer);
     137             : 
     138           0 :         printf ("Asynchronous Notification Example Application\n");
     139           0 :         printf ("Please note that notification transport plugins are required see\n"
     140             :                 " https://www.libelektra.org/tutorials/notifications#notification-configuration!\n");
     141           0 :         printf ("- Set \"%s\" to red, blue or green to change the text color\n", keyName (callbackKeyToWatch));
     142           0 :         printf ("- Set \"%s\" to any integer value\n", keyName (intKeyToWatch));
     143           0 :         printf ("Send SIGINT (Ctl+C) to exit.\n\n");
     144             : 
     145             :         // Get configuration
     146           0 :         kdbGet (kdb, config, key);
     147           0 :         printVariable (timer); // "value" was automatically updated
     148             : 
     149             :         // This allows us to wake the loop from our signal handler
     150             : #ifdef HAVE_LIBUV1
     151           0 :         uv_async_init (loop, &wakeup, NULL);
     152             : #else
     153             :         uv_async_init (loop, &wakeup, wakeupCallback);
     154             : #endif
     155             : 
     156           0 :         uv_run (loop, UV_RUN_DEFAULT);
     157             : 
     158             :         // Cleanup
     159             :         resetTerminalColor ();
     160           0 :         elektraIoBindingRemoveTimer (timer);
     161           0 :         elektraFree (timer);
     162           0 :         elektraNotificationClose (kdb);
     163           0 :         kdbClose (kdb, key);
     164             : 
     165           0 :         elektraIoBindingCleanup (binding);
     166           0 :         uv_run (loop, UV_RUN_NOWAIT);
     167             : #ifdef HAVE_LIBUV1
     168           0 :         uv_loop_close (uv_default_loop ());
     169             : #else
     170             :         uv_loop_delete (uv_default_loop ());
     171             : #endif
     172             : 
     173           0 :         ksDel (config);
     174           0 :         keyDel (intKeyToWatch);
     175           0 :         keyDel (callbackKeyToWatch);
     176           0 :         keyDel (key);
     177           0 :         printf ("cleanup done!\n");
     178             : }

Generated by: LCOV version 1.13