This is useful if an application is using 2 different devices,
and want logging to be split by device, or if application logging
needs some private context.

Care has been taken to not break the API/ABI and only add new functions,
or only modify private structures.

A drawback is that when dvb_fe_open_flags() is called, the custom function
can not be set yet, so dvb_fe_open_flags() will log errors using the old
function without private context.

Signed-off-by: Rafaël Carré <fun...@videolan.org>
---
 lib/include/libdvbv5/dvb-dev.h | 21 ++++++++++++
 lib/include/libdvbv5/dvb-log.h | 73 ++++++++++++++++++++----------------------
 lib/libdvbv5/dvb-dev.c         | 13 ++++++++
 lib/libdvbv5/dvb-fe-priv.h     |  3 ++
 lib/libdvbv5/dvb-fe.c          |  8 +++++
 utils/dvb/dvbv5-daemon.c       |  9 +++---
 6 files changed, 85 insertions(+), 42 deletions(-)

diff --git a/lib/include/libdvbv5/dvb-dev.h b/lib/include/libdvbv5/dvb-dev.h
index 55e0f065..6dbd2ae7 100644
--- a/lib/include/libdvbv5/dvb-dev.h
+++ b/lib/include/libdvbv5/dvb-dev.h
@@ -234,6 +234,27 @@ struct dvb_dev_list *dvb_get_dev_info(struct dvb_device 
*dvb,
  */
 void dvb_dev_stop_monitor(struct dvb_device *dvb);
 
+/**
+ * @brief Sets the DVB verbosity and log function with context private data
+ * @ingroup dvb_device
+ *
+ * @param dvb          pointer to struct dvb_device to be used
+ * @param verbose      Verbosity level of the messages that will be printed
+ * @param logfunc      Callback function to be called when a log event
+ *                     happens. Can either store the event into a file or
+ *                     to print it at the TUI/GUI. Can be null.
+ * @param logpriv   Private data for log function
+ *
+ * @details Sets the function to report log errors and to set the verbosity
+ *     level of debug report messages. If not called, or if logfunc is
+ *     NULL, the libdvbv5 will report error and debug messages via stderr,
+ *     and will use colors for the debug messages.
+ *
+ */
+void dvb_dev_set_logpriv(struct dvb_device *dvb,
+                    unsigned verbose,
+                    dvb_logfunc_priv logfunc, void *logpriv);
+
 /**
  * @brief Sets the DVB verbosity and log function
  * @ingroup dvb_device
diff --git a/lib/include/libdvbv5/dvb-log.h b/lib/include/libdvbv5/dvb-log.h
index 181a23c8..23cceede 100644
--- a/lib/include/libdvbv5/dvb-log.h
+++ b/lib/include/libdvbv5/dvb-log.h
@@ -43,61 +43,58 @@
 
 typedef void (*dvb_logfunc)(int level, const char *fmt, ...) __attribute__ (( 
format( printf, 2, 3 )));
 
+/**
+ * @typedef void (*dvb_logfunc)(void *logpriv, int level, const char *fmt, ...)
+ * @brief typedef used by dvb_fe_open2 for the log function with private 
context
+ * @ingroup ancillary
+ */
+
+typedef void (*dvb_logfunc_priv)(void *logpriv, int level, const char *fmt, 
...);
+
 /*
  * Macros used internally inside libdvbv5 frontend part, to output logs
  */
 
 #ifndef _DOXYGEN
 
-#ifndef __DVB_FE_PRIV_H
+struct dvb_v5_fe_parms;
+/**
+ * @brief retrieve the logging function with private data from the private fe 
params.
+ */
+dvb_logfunc_priv dvb_get_log_priv(struct dvb_v5_fe_parms *, void **);
 
-#define dvb_log(fmt, arg...) do {\
-       parms->logfunc(LOG_INFO, fmt, ##arg); \
-} while (0)
-#define dvb_logerr(fmt, arg...) do {\
-       parms->logfunc(LOG_ERR, fmt, ##arg); \
-} while (0)
-#define dvb_logdbg(fmt, arg...) do {\
-       parms->logfunc(LOG_DEBUG, fmt, ##arg); \
-} while (0)
-#define dvb_logwarn(fmt, arg...) do {\
-       parms->logfunc(LOG_WARNING, fmt, ##arg); \
-} while (0)
-#define dvb_loginfo(fmt, arg...) do {\
-       parms->logfunc(LOG_NOTICE, fmt, ##arg); \
-} while (0)
+#ifndef __DVB_FE_PRIV_H
 
-#define dvb_perror(msg) do {\
-       parms->logfunc(LOG_ERR, "%s: %s", msg, strerror(errno)); \
+#define dvb_loglevel(level, fmt, arg...) do {\
+    void *priv;\
+    dvb_logfunc_priv f = dvb_get_log_priv(parms, &priv);\
+    if (f) {\
+        f(priv, level, fmt, ##arg);\
+    } else {\
+        parms->logfunc(level, fmt, ##arg); \
+    }\
 } while (0)
 
 #else
 
-#define dvb_log(fmt, arg...) do {\
-       parms->p.logfunc(LOG_INFO, fmt, ##arg); \
-} while (0)
-#define dvb_logerr(fmt, arg...) do {\
-       parms->p.logfunc(LOG_ERR, fmt, ##arg); \
-} while (0)
-#define dvb_logdbg(fmt, arg...) do {\
-       parms->p.logfunc(LOG_DEBUG, fmt, ##arg); \
-} while (0)
-#define dvb_logwarn(fmt, arg...) do {\
-       parms->p.logfunc(LOG_WARNING, fmt, ##arg); \
-} while (0)
-#define dvb_loginfo(fmt, arg...) do {\
-       parms->p.logfunc(LOG_NOTICE, fmt, ##arg); \
-} while (0)
 #define dvb_loglevel(level, fmt, arg...) do {\
-       parms->p.logfunc(level, fmt, ##arg); \
-} while (0)
-
-#define dvb_perror(msg) do {\
-       parms->p.logfunc(LOG_ERR, "%s: %s", msg, strerror(errno)); \
+    if (parms->logfunc_priv) {\
+        parms->logfunc_priv(parms->logpriv, level, fmt, ##arg);\
+    } else {\
+        parms->p.logfunc(level, fmt, ##arg); \
+    }\
 } while (0)
 
 #endif
 
+#define dvb_log(fmt, arg...) dvb_loglevel(LOG_INFO, fmt, ##arg)
+#define dvb_logerr(fmt, arg...) dvb_loglevel(LOG_ERR, fmt, ##arg)
+#define dvb_logdbg(fmt, arg...) dvb_loglevel(LOG_DEBUG, fmt, ##arg)
+#define dvb_logwarn(fmt, arg...) dvb_loglevel(LOG_WARNING, fmt, ##arg)
+#define dvb_loginfo(fmt, arg...) dvb_loglevel(LOG_NOTICE, fmt, ##arg)
+
+#define dvb_perror(msg) dvb_logerr("%s: %s", msg, strerror(errno))
+
 #endif /* _DOXYGEN */
 
 /**
diff --git a/lib/libdvbv5/dvb-dev.c b/lib/libdvbv5/dvb-dev.c
index e6a8fc76..9a0952b4 100644
--- a/lib/libdvbv5/dvb-dev.c
+++ b/lib/libdvbv5/dvb-dev.c
@@ -162,6 +162,19 @@ struct dvb_dev_list *dvb_dev_seek_by_adapter(struct 
dvb_device *d,
        return ops->seek_by_adapter(dvb, adapter, num, type);
 }
 
+void dvb_dev_set_logpriv(struct dvb_device *dvb, unsigned verbose,
+                    dvb_logfunc_priv logfunc_priv, void *logpriv)
+{
+       struct dvb_v5_fe_parms_priv *parms = (void *)dvb->fe_parms;
+
+       /* FIXME: how to get remote logs and set verbosity? */
+       parms->p.verbose = verbose;
+       parms->logpriv = logpriv;
+
+       if (logfunc_priv != NULL)
+                       parms->logfunc_priv = logfunc_priv;
+}
+
 void dvb_dev_set_log(struct dvb_device *dvb, unsigned verbose,
                     dvb_logfunc logfunc)
 {
diff --git a/lib/libdvbv5/dvb-fe-priv.h b/lib/libdvbv5/dvb-fe-priv.h
index 5bf2b22b..239c48f8 100644
--- a/lib/libdvbv5/dvb-fe-priv.h
+++ b/lib/libdvbv5/dvb-fe-priv.h
@@ -75,6 +75,9 @@ struct dvb_v5_fe_parms_priv {
        /* Satellite specific stuff */
        int                             high_band;
        unsigned                        freq_offset;
+
+       dvb_logfunc_priv                logfunc_priv;
+       void                            *logpriv;
 };
 
 /* Functions used internally by dvb-dev.c. Aren't part of the API */
diff --git a/lib/libdvbv5/dvb-fe.c b/lib/libdvbv5/dvb-fe.c
index 39923fe4..5327df29 100644
--- a/lib/libdvbv5/dvb-fe.c
+++ b/lib/libdvbv5/dvb-fe.c
@@ -28,6 +28,7 @@
 #include <stddef.h>
 #include <time.h>
 #include <unistd.h>
+#include <stdarg.h>
 
 #include <config.h>
 
@@ -1899,3 +1900,10 @@ int dvb_fe_set_default_country(struct dvb_v5_fe_parms 
*p, const char *cc)
        parms->country = dvb_country_a2_to_id(cc);
        return (parms->country == COUNTRY_UNKNOWN) ? -EINVAL : 0;
 }
+
+dvb_logfunc_priv dvb_get_log_priv(struct dvb_v5_fe_parms *p, void **priv)
+{
+       struct dvb_v5_fe_parms_priv *parms = (void *)p;
+       *priv = parms->logpriv;
+       return parms->logfunc_priv;
+}
diff --git a/utils/dvb/dvbv5-daemon.c b/utils/dvb/dvbv5-daemon.c
index f0098c2b..c26886dd 100644
--- a/utils/dvb/dvbv5-daemon.c
+++ b/utils/dvb/dvbv5-daemon.c
@@ -553,12 +553,13 @@ static ssize_t scan_data(char *buf, int buf_size, const 
char *fmt, ...)
 /*
  * Remote log
  */
-void dvb_remote_log(int level, const char *fmt, ...)
+void dvb_remote_log(void *priv, int level, const char *fmt, ...)
 {
        int ret;
        char *buf;
 
        va_list ap;
+       int fd = *(int*)priv;
 
        va_start(ap, fmt);
        ret = vasprintf(&buf, fmt, ap);
@@ -569,8 +570,8 @@ void dvb_remote_log(int level, const char *fmt, ...)
 
        va_end(ap);
 
-       if (dvb_fd >= 0)
-               send_data(dvb_fd, "%i%s%i%s", 0, "log", level, buf);
+       if (fd >= 0)
+               send_data(fd, "%i%s%i%s", 0, "log", level, buf);
        else
                local_log(level, buf);
 
@@ -1486,7 +1487,7 @@ int main(int argc, char *argv[])
        }
 
        /* FIXME: should allow the caller to set the verbosity */
-       dvb_dev_set_log(dvb, 1, dvb_remote_log);
+       dvb_dev_set_logpriv(dvb, 1, dvb_remote_log, &dvb_fd);
 
        /* Listen up to 5 connections */
        listen(sockfd, 5);
-- 
2.14.1

Reply via email to