separation cleanup

Jean-Francois Dockes Jean-Francois Dockes 2014-10-12

1 2 3 > >> (Page 1 of 3)
added .gitignore
removed src
removed src/control
removed src/control/httpdownload.hxx
removed src/soaphelp.cxx
removed src/soaphelp.hxx
removed src/upnpp_p.hxx
removed src/upnpplib.cxx
removed src/upnpplib.hxx
removed src/upnpputils.hxx
removed src/workqueue.hxx
changed debian/changelog
changed debian/control
changed debian/copyright
changed debian/watch
changed rpm/upmpdcli.spec
changed Makefile.am
changed configure.ac
copied debian/postinst -> libupnpp/control/httpdownload.hxx
copied debian/upmpdcli.init -> libupnpp/soaphelp.hxx
copied src/control/#cdircontent.hxx# -> libupnpp/control/cdircontent.hxx
copied src/control/#cdirectory.cxx# -> libupnpp/control/cdirectory.cxx
copied src/control/#cdirectory.hxx# -> libupnpp/control/cdirectory.hxx
copied src/control/#discovery.cxx# -> libupnpp/control/discovery.cxx
copied src/control/#mediaserver.cxx# -> libupnpp/control/mediaserver.cxx
.gitignore Diff Switch to side-by-side view
Loading...
src
File was removed.
src/control
File was removed.
src/control/httpdownload.hxx
File was removed.
src/soaphelp.cxx
File was removed.
src/soaphelp.hxx
File was removed.
src/upnpp_p.hxx
File was removed.
src/upnpplib.cxx
File was removed.
src/upnpplib.hxx
File was removed.
src/upnpputils.hxx
File was removed.
src/workqueue.hxx
File was removed.
debian/changelog Diff Switch to side-by-side view
Loading...
debian/control Diff Switch to side-by-side view
Loading...
debian/copyright Diff Switch to side-by-side view
Loading...
debian/watch Diff Switch to side-by-side view
Loading...
rpm/upmpdcli.spec Diff Switch to side-by-side view
Loading...
Makefile.am Diff Switch to side-by-side view
Loading...
configure.ac Diff Switch to side-by-side view
Loading...
debian/postinst to libupnpp/control/httpdownload.hxx
--- a/debian/postinst
+++ b/libupnpp/control/httpdownload.hxx
@@ -1,15 +1,9 @@
-#! /bin/sh
-# postinst for upmpdcli
+#ifndef _HTTPDOWNLOAD_H_X_INCLUDED_
+#define _HTTPDOWNLOAD_H_X_INCLUDED_
 
-set -e
+#include <string>
 
-if [ "$1" = configure ]; then
-    if ! getent passwd upmpdcli > /dev/null; then
-	adduser --disabled-password --quiet --system \
-	    --home /nonexistent --no-create-home --shell /bin/false upmpdcli
-    fi
-fi
+extern bool downloadUrlWithCurl(const std::string& url, 
+                                std::string& out, long timeoutsecs);
 
-#DEBHELPER#
-
-exit 0
+#endif /* _HTTPDOWNLOAD.H_X_INCLUDED_ */
debian/upmpdcli.init to libupnpp/soaphelp.hxx
--- a/debian/upmpdcli.init
+++ b/libupnpp/soaphelp.hxx
@@ -1,149 +1,119 @@
-#!/bin/sh
-### BEGIN INIT INFO
-# Provides:          upmpdcli
-# Required-Start:    $network $local_fs $remote_fs 
-# Required-Stop:     $remote_fs
-# Default-Start:     2 3 4 5
-# Default-Stop:      0 1 6
-# Short-Description: UPnP Renderer front-end to MPD
-# Description: upmpdcli is as an UPnP Media Renderer front-end 
-#    to MPD, and enables you to control it with any UPnP controller
-#    running, for example, on an Android tablet. It uses the MPD
-#    instance to actually play the tracks. A typical configuration
-#    would have for example, MPD running on a Raspberry PI, with
-#    upmpdcli on the same host or any other Linux PC on the network.
-### END INIT INFO
+/* Copyright (C) 2014 J.F.Dockes
+ *	 This program 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 2 of the License, or
+ *	 (at your option) any later version.
+ *
+ *	 This program 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 this program; if not, write to the
+ *	 Free Software Foundation, Inc.,
+ *	 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#ifndef _SOAPHELP_H_X_INCLUDED_
+#define _SOAPHELP_H_X_INCLUDED_
 
-# Author: Jean-Francois Dockes <jf@dockes.org>
+#include <upnp/ixml.h>                  // for IXML_Document
 
-# PATH should only include /usr/* if it runs after the mountnfs.sh script
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
-DESC=upmpdcli             # Introduce a short description here
-NAME=upmpdcli             # Introduce the short server's name here
-DAEMON=/usr/bin/upmpdcli # Introduce the server's location here
-DAEMON_ARGS="-D -c /etc/upmpdcli.conf"    # Arguments to run the daemon with
-PIDFILE=/var/run/$NAME.pid
-SCRIPTNAME=/etc/init.d/$NAME
+#include <map>                          // for map
+#include <string>                       // for string
+#include <unordered_map>                // for unordered_map
+#include <utility>                      // for pair
+#include <vector>                       // for vector
 
-# Exit if the package is not installed
-[ -x $DAEMON ] || exit 0
+namespace UPnPP {
 
-# Read configuration variable file if it is present
-[ -r /etc/default/$NAME ] && . /etc/default/$NAME
+/** Store returned values after decoding the arguments in a SOAP Call */
+class SoapDecodeOutput {
+public:
+    std::string name;
+    std::map<std::string, std::string> args;
 
-# Load the VERBOSE setting and other rcS variables
-. /lib/init/vars.sh
+    // Utility methods
+    bool getBool(const char *nm, bool *value) const;
+    bool getInt(const char *nm, int *value) const;
+    bool getString(const char *nm, std::string *value) const;
+    bool get(const char *nm, bool *value) const {return getBool(nm, value);}
+    bool get(const char *nm, int *value) const {return getInt(nm, value);}
+    bool get(const char *nm, std::string *value) const {return getString(nm, value);}
+};
 
-# Define LSB log_* functions.
-# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
-. /lib/lsb/init-functions
+/** Decode the XML in a Soap call and return the arguments in a SoapArgs 
+ * structure.
+ *
+ * @param name the action name is stored for convenience in the return
+ * structure. The caller normally gets it from libupnp, passing it is simpler
+ * than retrieving from the input top node where it has a namespace qualifier.
+ * @param actReq the XML document containing the SOAP data.
+ * @param[output] res the decoded data.
+ * @return true for success, false if a decoding error occurred.
+ */
+extern bool decodeSoapBody(const char *name, IXML_Document *actReq, 
+                           SoapDecodeOutput *res);
 
-#
-# Function that starts the daemon/service
-#
-do_start()
-{
-	# Return
-	#   0 if daemon has been started
-	#   1 if daemon was already running
-	#   2 if daemon could not be started
-	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
-		|| return 1
-	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
-		$DAEMON_ARGS \
-		|| return 2
-	# Add code here, if necessary, that waits for the process to be ready
-	# to handle requests from services started subsequently which depend
-	# on this one.  As a last resort, sleep for some time.
-}
+/** Store the values to be encoded in a SOAP response. 
+ *
+ * The elements in the response must be in a defined order, so we
+ * can't use a map as container, we use a vector of pairs instead.
+ * The generic UpnpDevice callback fills up name and service type, the
+ * device call only needs to fill the data vector.
+ */
+class SoapEncodeInput {
+public:
+    SoapEncodeInput() {}
+    SoapEncodeInput(const std::string& st, const std::string& nm)
+        : serviceType(st), name(nm) {}
+    SoapEncodeInput& addarg(const std::string& k, const std::string& v) {
+        data.push_back(std::pair<std::string, std::string>(k, v));
+        return *this;
+    }
+    SoapEncodeInput& operator() (const std::string& k, const std::string& v) {
+        data.push_back(std::pair<std::string, std::string>(k, v));
+        return *this;
+    }
+    static std::string i2s(int val);
+    std::string serviceType;
+    std::string name;
+    std::vector<std::pair<std::string, std::string> > data;
+};
 
-#
-# Function that stops the daemon/service
-#
-do_stop()
-{
-	# Return
-	#   0 if daemon has been stopped
-	#   1 if daemon was already stopped
-	#   2 if daemon could not be stopped
-	#   other if a failure occurred
-	start-stop-daemon --stop --quiet --retry=TERM/5/KILL/5 --pidfile $PIDFILE --name $NAME
-	RETVAL="$?"
-	[ "$RETVAL" = 2 ] && return 2
-	# Many daemons don't delete their pidfiles when they exit.
-	rm -f $PIDFILE
-	return "$RETVAL"
-}
+// Until we can fix the device code.
+typedef SoapEncodeInput SoapData;
+typedef SoapDecodeOutput SoapArgs;
 
-#
-# Function that sends a SIGHUP to the daemon/service
-#
-#do_reload() {
-	#
-	# If the daemon can reload its configuration without
-	# restarting (for example, when it is sent a SIGHUP),
-	# then implement that here.
-	#
-#	start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
-#	return 0
-#}
+/** Build a SOAP response data XML document from a list of values */
+extern IXML_Document *buildSoapBody(const SoapEncodeInput& data, 
+                                    bool isResp = true);
 
-case "$1" in
-  start)
-    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
-    do_start
-    case "$?" in
-		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
-		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
-	esac
-  ;;
-  stop)
-	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
-	do_stop
-	case "$?" in
-		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
-		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
-	esac
-	;;
-  status)
-       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
-       ;;
-  #reload|force-reload)
-	#
-	# If do_reload() is not implemented then leave this commented out
-	# and leave 'force-reload' as an alias for 'restart'.
-	#
-	#log_daemon_msg "Reloading $DESC" "$NAME"
-	#do_reload
-	#log_end_msg $?
-	#;;
-  restart|force-reload)
-	#
-	# If the "reload" option is implemented then remove the
-	# 'force-reload' alias
-	#
-	log_daemon_msg "Restarting $DESC" "$NAME"
-	do_stop
-	case "$?" in
-	  0|1)
-		do_start
-		case "$?" in
-			0) log_end_msg 0 ;;
-			1) log_end_msg 1 ;; # Old process is still running
-			*) log_end_msg 1 ;; # Failed to start
-		esac
-		;;
-	  *)
-	  	# Failed to stop
-		log_end_msg 1
-		;;
-	esac
-	;;
-  *)
-	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
-	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
-	exit 3
-	;;
-esac
+namespace SoapHelp {
+    std::string xmlQuote(const std::string& in);
+    std::string xmlUnquote(const std::string& in);
+    std::string i2s(int val);
+    inline std::string val2s(const std::string& val) {return val;}
+    inline std::string val2s(int val) {return i2s(val);}
+    inline std::string val2s(bool val) {return i2s(int(val));}
+};
 
-:
+/** Decode UPnP Event data. This is not soap, but it's quite close to
+ *  the other code in here so whatever...
+ *
+ * The variable values are contained in a propertyset XML document:
+ *     <?xml version="1.0"?>
+ *     <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
+ *       <e:property>
+ *         <variableName>new value</variableName>
+ *       </e:property>
+ *       <!-- Other variable names and values (if any) go here. -->
+ *     </e:propertyset>
+ */
+extern bool decodePropertySet(IXML_Document *doc, 
+                       std::unordered_map<std::string,std::string>& out);
+
+
+} // namespace UPnPP
+
+#endif /* _SOAPHELP_H_X_INCLUDED_ */
src/control/#cdircontent.hxx# to libupnpp/control/cdircontent.hxx
--- a/src/control/#cdircontent.hxx#
+++ b/libupnpp/control/cdircontent.hxx
@@ -108,13 +108,15 @@
 
     }
 
-    // Sim
-    std::string f2s(const std::string& nm, bool isres) {
-        string val;
-        if (isres) {
-            dop.getrprop(0, nm, val);
+    /** Simplified interface to retrieving values: we don't distinguish
+     * between non-existing and empty, and we only use the first ressource
+     */
+    std::string f2s(const std::string& nm, bool isresfield) {
+        std::string val;
+        if (isresfield) {
+            getrprop(0, nm, val);
         } else {
-            dop.getprop(nm, val);
+            getprop(nm, val);
         }
         return val;
     }
src/control/#cdirectory.cxx# to libupnpp/control/cdirectory.cxx
--- a/src/control/#cdirectory.cxx#
+++ b/libupnpp/control/cdirectory.cxx
@@ -18,7 +18,9 @@
 
 #include "libupnpp/control/cdirectory.hxx"
 
-#include <regexp.h>
+#include <sys/types.h>
+#include <regex.h>
+
 #include <upnp/upnp.h>                  // for UPNP_E_SUCCESS, etc
 #include <upnp/upnptools.h>             // for UpnpGetErrorMessage
 
@@ -44,15 +46,16 @@
 const string ContentDirectory::SType("urn:schemas-upnp-org:service:ContentDirectory:1");
 
 class SimpleRegexp {
+public:
     SimpleRegexp(const string& exp, int flags) : m_ok(false) {
-        if (regcomp(exp.c_str(), &m_expr, flags) == 0) {
+        if (regcomp(&m_expr, exp.c_str(), flags) == 0) {
             m_ok = true;
         }
     }
     ~SimpleRegexp() {
         regfree(&m_expr);
     }
-    bool simpleMatch(const string& val) {
+    bool simpleMatch(const string& val) const {
         if (!ok())
             return false;
         if (regexec(&m_expr, val.c_str(), 0, 0, 0) == 0) {
@@ -61,11 +64,11 @@
             return false;
         }
     }
-    bool operator() (const string& val) {
+    bool operator() (const string& val) const {
         return simpleMatch(val);
     }
 
-    bool ok() {return m_ok;}
+    bool ok() const {return m_ok;}
 private:
     bool m_ok;
     regex_t m_expr;
@@ -78,11 +81,11 @@
   manufacturer: PacketVideo model TwonkyMedia Server
   manufacturer: ? model MediaTomb
 */
-static const SimpleRegexp bubble_rx(".*bubble.*", REG_ICASE);
-static const SimpleRegexp mediatomb_rx(".*mediatomb.*", REG_ICASE);
-static const SimpleRegexp minidlna_rx(".*minidlna.*", REG_ICASE);
-static const SimpleRegexp minim_rx(".*minim.*", REG_ICASE);
-static const SimpleRegexp twonky_rx(".*twonky.*", REG_ICASE);
+static const SimpleRegexp bubble_rx("bubble", REG_ICASE|REG_NOSUB);
+static const SimpleRegexp mediatomb_rx("mediatomb", REG_ICASE|REG_NOSUB);
+static const SimpleRegexp minidlna_rx("minidlna", REG_ICASE|REG_NOSUB);
+static const SimpleRegexp minim_rx("minim", REG_ICASE|REG_NOSUB);
+static const SimpleRegexp twonky_rx("twonky", REG_ICASE|REG_NOSUB);
 
 ContentDirectory::ContentDirectory(const UPnPDeviceDesc& device,
                                    const UPnPServiceDesc& service)
@@ -93,17 +96,22 @@
 
     if (bubble_rx(m_modelName)) {
         m_serviceKind = CDSKIND_BUBBLE;
+        LOGDEB1("ContentDirectory::ContentDirectory: BUBBLE" << endl);
     } else if (mediatomb_rx(m_modelName)) {
         // Readdir by 200 entries is good for most, but MediaTomb likes
         // them really big. Actually 1000 is better but I don't dare
         m_rdreqcnt = 500;
         m_serviceKind = CDSKIND_MEDIATOMB;
+        LOGDEB1("ContentDirectory::ContentDirectory: MEDIATOMB" << endl);
     } else if (minidlna_rx(m_modelName)) {
         m_serviceKind = CDSKIND_MINIDLNA;
+        LOGDEB1("ContentDirectory::ContentDirectory: MINIDLNA" << endl);
     } else if (minim_rx(m_modelName)) {
         m_serviceKind = CDSKIND_MINIM;
+        LOGDEB1("ContentDirectory::ContentDirectory: MINIM" << endl);
     } else if (twonky_rx(m_modelName)) {
-        m_serviceKind = CDSKIND_MINIM;
+        m_serviceKind = CDSKIND_TWONKY;
+        LOGDEB1("ContentDirectory::ContentDirectory: TWONKY" << endl);
     } 
     registerCallback();
 }
src/control/#cdirectory.hxx# to libupnpp/control/cdirectory.hxx
--- a/src/control/#cdirectory.hxx#
+++ b/libupnpp/control/cdirectory.hxx
@@ -61,7 +61,7 @@
     ContentDirectory() : m_rdreqcnt(200), m_serviceKind(CDSKIND_UNKNOWN) {}
 
     enum ServiceKind {CDSKIND_UNKNOWN, CDSKIND_BUBBLE, CDSKIND_MEDIATOMB,
-                      CDSKIND_MINIDLNA, CDSKIND_MINIM, CDSKIND_TWO};
+                      CDSKIND_MINIDLNA, CDSKIND_MINIM, CDSKIND_TWONKY};
 
     ServiceKind getKind() {return m_serviceKind;}
 
src/control/#discovery.cxx# to libupnpp/control/discovery.cxx
--- a/src/control/#discovery.cxx#
+++ b/libupnpp/control/discovery.cxx
@@ -131,7 +131,7 @@
                 PTMutexLocker lock(o_downloading_mutex);
                 auto res = o_downloading.insert(tp->url);
                 if (!res.second) {
-                    LOGDEB("discoExplorer: already downloading " << 
+                    LOGDEB("discovery:cllb: already downloading " << 
                            tp->url << endl);
                     return UPNP_E_SUCCESS;
                 }
@@ -140,7 +140,7 @@
             LOGDEB("discoExplorer: downloading " << tp->url << endl);
             string sdesc;
             if (!downloadUrlWithCurl(tp->url, tp->description, 5)) {
-                LOGERR("discoExplorer: downloadUrlWithCurl error for: " << 
+                LOGERR("discovery:cllb: downloadUrlWithCurl error for: " << 
                        tp->url << endl);
                 {PTMutexLocker lock(o_downloading_mutex);
                     o_downloading.erase(tp->url);
@@ -148,7 +148,7 @@
                 delete tp;
                 return UPNP_E_SUCCESS;
             }
-            LOGDEB1("discoExplorer: downloaded description document of " <<
+            LOGDEB1("discovery:cllb: downloaded description document of " <<
                     tp->description.size() << " bytes" << endl);
 
             {PTMutexLocker lock(o_downloading_mutex);
@@ -266,8 +266,8 @@
                     << " devtype " << d.device.deviceType << endl);
             {
                 PTMutexLocker lock(o_pool.m_mutex);
-               LOGINFO("discoExplorer: inserting device id "<< tsk->deviceId
-                        <<  " description: " << endl << d.device.dump() << endl);
+                //LOGDEB1("discoExplorer: inserting device id "<< tsk->deviceId
+                // <<  " description: " << endl << d.device.dump() << endl);
                 o_pool.m_devices[tsk->deviceId] = d;
             }
             {
src/control/#mediaserver.cxx# to libupnpp/control/mediaserver.cxx
--- a/src/control/#mediaserver.cxx#
+++ b/libupnpp/control/mediaserver.cxx
@@ -75,7 +75,6 @@
 }
 
 MediaServer::MediaServer(const UPnPDeviceDesc& desc)
-    : m_serverKind(MSKIND_UNKNOWN)
 {
     bool found = false;
     for (auto it = desc.services.begin(); it != desc.services.end(); it++) {
@@ -89,7 +88,6 @@
         LOGERR("MediaServer::MediaServer: ContentDirectory service not "
                "found in device" << endl);
     }
-    if (str
 }
 
 }
1 2 3 > >> (Page 1 of 3)