Index: /tags/help/iwearrpc/PHASE
===================================================================
--- /tags/help/iwearrpc/PHASE (revision 2257)
+++ /tags/help/iwearrpc/PHASE (revision 2257)
@@ -0,0 +1,2 @@
+Currently Active Phase:
+Phase 2 (adding more features, stabilizing codebase)
Index: /tags/help/iwearrpc/configure
===================================================================
--- /tags/help/iwearrpc/configure (revision 2252)
+++ /tags/help/iwearrpc/configure (revision 2252)
@@ -0,0 +1,283 @@
+#!/usr/bin/env bash
+#!/bin/bash
+#
+#
+# This is not generated by autoconf or similar, just handcoded, since we don't
+# need this much complexity
+
+# Our configuration for the makefiles !!
+PREFIX="$HOME"
+SYSCONF="$PREFIX/etc/"
+LIBNAME=libiwremote
+DISTNAME=iwremote
+DISTDIR=iwremote
+VERSION=0.6.0
+
+# include the check function library
+. ./functions
+
+SRCDIRS="src"
+LIBS=-lpthread
+LIBLIBS="-liwear_core"
+INCLUDES="-I \$(TOPDIR)/include/"
+
+EXTRACLEANFILES="test doxygen.log libiw* idl/*.o idl/*.h idl/*.c idl/*.cc"
+STERILFILES="*.tag lib/*.a lib/*.so* include/config.h makefile.conf"
+STERILDIRS=
+
+# Files to be linked together to the library
+LIBFILES_parser="
+"
+
+LIBFILES_src="
+chainsecurityprovider.o
+callmanager.o
+callprovider.o
+class.o
+cppoutput.o
+declaration.o
+enum.o
+function.o
+idloutput.o
+namespace.o
+remoteconnection.o
+remoteobject.o
+rootartano.o
+socketprovider.o
+socketremoteconnection.o
+translationunit.o
+xdrstream.o
+"
+#nullstream.o
+
+LIBFILES_idl="
+"
+
+# internal configuration and needed versions
+CONFLOG=config.log
+
+CONFIG_H=./include/config.h
+
+MIN_MAKE="3.78"
+MIN_GCC="3.3.0"
+MIN_GPP="3.3.1"
+MIN_SSL="0.9.7a"
+MIN_GLIB2="2.2.3"
+MIN_ORBIT2="2.8.3"
+#MIN_ORBITCPP="1.3.9"
+MIN_ORBITCPP="0.30.2"
+MIN_XERCES="2.5.0"
+
+#
+# End of configurable stuff
+#
+
+echo "Starting automagix config script" > $CONFLOG
+
+check_sed
+
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+# "stolen" from autoconf {{{
+ac_prev=
+ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+for ac_option
+do
+# If the previous option needs an argument, assign it.
+    if test -n "$ac_prev"; then
+	eval "$ac_prev=\$ac_option"
+	ac_prev=
+	continue
+    fi
+
+    ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+
+    case $ac_option in
+	-no-pkg-config | --no-pkg-config | --no-pkg-config | --no-pkg-confi | --no-pkg-conf | --no-pkg-con | --no-pkg-co | --no-pkg-c | --no-pkg- | --no-pkg | --no-pk | --no-p)
+       	    NO_PKG_CONFIG=yes ;;		
+	-sysconfdir |  --sysconfdir |	--sysconfdi |	--sysconfd |	--sysconf |	--syscon |	--sysco |	--sysc |	--sys |	--sy |	--s)
+	    ac_prev=SYSCONF ;;
+
+	-sysconfdir=* |  --sysconfdir=* |	--sysconfdi=* |	--sysconfd=* |	--sysconf=* |	--syscon=* |	--sysco=* |	--sysc=* |	--sys=* |	--sy=* |	--s=*)
+	    SYSCONF="$ac_optarg" ;;
+
+	-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+	    ac_prev=PREFIX ;;
+	-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+	    PREFIX="$ac_optarg" ;;
+	-force-gpp | --force-gpp | --force-gp)
+	    FORCEGPP=yes ;;	
+	-force-gcc | --force-gcc | --force-gc)
+	    FORCEGCC=yes ;;
+	-help | --help | --hel | --he | -h)
+	    HELP=yes ;;
+
+	*=*)
+	    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+	    # Reject names that are not valid shell variable names.
+	    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+	    { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+	    { (cleanup; exit 1); cleanup; exit 1; }; }
+	    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+	    eval "$ac_envvar='$ac_optarg'"
+	    export $ac_envvar ;;
+    esac
+done
+# }}}
+
+eval PREFIX='$PREFIX'
+eval SYSCONF='$SYSCONF'
+
+if [ ! -z "$HELP" ]
+then
+#	echo "help"
+#	echo -e "Unrecognized argument \"$1\"\n"
+	echo -e "Valid options are :"
+	echo -e ""
+	echo -e "Fine Tuning of library and include directories:"
+	echo -e ""
+	echo -e "Other Options:"
+	echo -e "\t--force-gcc=yes\tForces configure to accept current C compiler version"
+	echo -e "\t--force-gpp=yes\tForces configure to accept current C++ compiler version"
+	echo -e "\t--no-pkg-config\tSkippes any search for pkg-config"
+	echo -e "\t--prefix=<path>\tPath prefix to install the program into. default is $PREFIX"
+	echo -e "\t--help\t\tDisplays this help screen"
+	echo -e ""
+	echo -e "Some influential environment variables:"
+	echo -e "  CC          C compiler command"
+	echo -e "  CFLAGS      C compiler flags"
+	echo -e "  CPPFLAGS    C++ Compiler flags, e.g. -I<include dir> if you have"
+	echo -e "              headers in a nonstandard directory <include dir>"
+	echo -e "  CPP         C++ Compiler"
+	echo -e ""
+	echo -e "Use these variables to override the choices made by \`configure' or to help"
+	echo -e "it to find libraries and programs with nonstandard names/locations."
+
+	cleanup; exit 0
+fi
+
+
+##############################################################################
+# GCC Version
+##############################################################################
+
+check_ostype
+check_dynlib
+
+check_gcc $MIN_GCC
+
+if [ $BAIL == "yes" ]
+then
+    echo "Your GCC is too old and does not support proper ISO C"
+    cleanup; exit 1
+fi
+
+##############################################################################
+# GCC Version
+##############################################################################
+
+check_gpp $MIN_GPP
+if [ $BAIL == "yes" ]
+then
+    echo "Your GCC is too old and does not support proper ISO C++"
+    cleanup; exit 1
+fi
+
+##############################################################################
+# gmake Version
+##############################################################################
+
+check_gmake $MIN_MAKE
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+#check_dlopen
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+#check_strnlen
+#check_strcasestr
+#check_vasprintf
+#check_strerror_r
+check_echo
+
+##############################################################################
+# pkg-config Version
+##############################################################################
+
+check_pkg_config
+
+#check_xerces $MIN_XERCES
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+#check_pgsql 7.3.2
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+#check_libpq
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+#check_libpqxx 2.1.3
+#check_ssl $MIN_SSL
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+#check_glib2 $MIN_GLIB2
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+#check_linc 
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+#check_orbit2 $MIN_ORBIT2
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+#check_orbitcpp $MIN_ORBITCPP
+if [ $BAIL == "yes" ]
+then
+    cleanup; exit 1
+fi
+
+
+check_doxygen
+BAIL=no
+
+gen_makefile makefile.conf
+
+gen_config $CONFIG_H
+
+echo -e "\nConfiguration :\n"
+echo -e "PREFIX\t\t$PREFIX"
+echo -e "SYSCONF\t\t$SYSCONF"
+echo -e "LIBDIR\t\t$PREFIX/lib"
+
+echo -e "\nWe are ready to compile. Type \"gmake lnk\"  and then \"gmake\" or \"gmake install\" to create and then install the software. If you plan to develop then \"gmake dep\" is a usefull feature too"
+
Index: /tags/help/iwearrpc/doxygen.conf
===================================================================
--- /tags/help/iwearrpc/doxygen.conf (revision 2256)
+++ /tags/help/iwearrpc/doxygen.conf (revision 2256)
@@ -0,0 +1,1250 @@
+# Doxyfile 1.4.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "iwear Remote Call Library"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 0.0.1
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = "exp=\par Experimental:\n" \
+                         "effect=\par Effects:\n" \
+                         "sideeffect=\par Side Effects:\n"
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = YES
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is YES.
+
+SHOW_DIRECTORIES       = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = .
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = *.c \
+                         *.cpp \
+                         *.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = YES
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = "sed 's/include <iwremote\//include </'"
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 3
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = IW
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = ./include/
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = _CLASS_DOCUMENTATION_ONLY_ \
+                         __cplusplus \
+                         "PH1=/** This has passed Phase 1 check */" \
+                         "PH2=/** This has passed Phase 2 check */" \
+                         "PH3=/** This has passed Phase 3 check */" \
+                         "PH4=/** This has passed Phase 4 check */" \
+                         "PH5=/** This has passed Phase 5 check */" \
+                         "PH6=/** This has passed Phase 6 check */"
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = ../iwear-src/iwear.tag \
+                         = \
+                         ../iwear-src/doc/html/
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = iwremote.tag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 2048
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 2048
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = NO
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
Index: /tags/help/iwearrpc/share/locale/de_DE/LC_MESSAGES/iwremote.po
===================================================================
--- /tags/help/iwearrpc/share/locale/de_DE/LC_MESSAGES/iwremote.po (revision 1183)
+++ /tags/help/iwearrpc/share/locale/de_DE/LC_MESSAGES/iwremote.po (revision 1183)
@@ -0,0 +1,26 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2004-11-18 15:46+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: src/callmanager.cpp:187 src/callmanager.cpp:218
+msgid "RPC Call Manager"
+msgstr "RPC Aufruf Manager"
+
+#: src/nullstream.cpp:33
+msgid "Warning, request for NULL RPC stream, system should shortcut call !"
+msgstr "Warnung, ein NULL RPC Stream wurde angefordert. Es sollte jedoch ein Shortcut-call durchgeführt werden !"
Index: /tags/help/iwearrpc/share/locale/iwremote.pot
===================================================================
--- /tags/help/iwearrpc/share/locale/iwremote.pot (revision 1183)
+++ /tags/help/iwearrpc/share/locale/iwremote.pot (revision 1183)
@@ -0,0 +1,26 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2004-11-18 15:46+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: src/callmanager.cpp:187 src/callmanager.cpp:218 src/callmanager.cpp:218
+msgid "RPC Call Manager"
+msgstr ""
+
+#: src/nullstream.cpp:33 src/nullstream.cpp:33
+msgid "Warning, request for NULL RPC stream, system should shortcut call !"
+msgstr ""
Index: /tags/help/iwearrpc/share/locale/Makefile
===================================================================
--- /tags/help/iwearrpc/share/locale/Makefile (revision 1183)
+++ /tags/help/iwearrpc/share/locale/Makefile (revision 1183)
@@ -0,0 +1,43 @@
+
+TOPDIR=../../
+NO_DEP_NEEDED=yes
+MASTER=iwremote.pot
+
+all: trans
+	
+include $(TOPDIR)/Makefile.common
+
+TRANSBASE=$(basename $(wildcard */LC_MESSAGES/*.po))
+MOFILES=$(addsuffix .mo, $(TRANSBASE))
+POFILES=$(addsuffix .po, $(TRANSBASE))
+POMFILES=$(addsuffix .pom, $(TRANSBASE))
+
+STERILFILES=$(MOFILES)
+
+
+MSGFMT=msgfmt -c
+
+trans: $(MOFILES)
+
+merge: $(POMFILES)
+	@$(MAKE) merge2
+
+merge2: $(POFILES)
+
+ifeq ($(MAKECMDGOALS),merge2)
+%.po:%.pom
+	@echo $(BLU)[MV]$(NOR) $*.pom $*.po
+	@mv $*.pom $*.po
+endif
+
+ifeq ($(MAKECMDGOALS),merge)
+
+%.pom:%.po
+	@echo $(TUK)[MSGMERGE]$(NOR) $*.po
+	@msgmerge -q $*.po $(MASTER) > $*.pom
+endif
+
+%.mo:%.po
+	@echo $(TUK)[MSGFMT]$(NOR) $*.mo
+	@msgfmt -o $*.mo $*.po
+
Index: /tags/help/iwearrpc/include/idloutput.h
===================================================================
--- /tags/help/iwearrpc/include/idloutput.h (revision 2229)
+++ /tags/help/iwearrpc/include/idloutput.h (revision 2229)
@@ -0,0 +1,74 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_IDLOUTPUT_H
+#define __IWREMOTE_IDLOUTPUT_H
+
+#include <iwremote/srcoutput.h>
+#include <iwremote/namespace.h>
+#include <iwremote/class.h>
+#include <iwremote/enum.h>
+#include <iwremote/function.h>
+#include <iwremote/declaration.h>
+
+namespace iwear
+{
+    namespace net
+    {
+class IDLOutput: public SrcOutput
+{
+private:
+protected:
+    string get_inds( uint32_t indlev );
+
+    void output_declaration( Declaration&, uint32_t );
+    void output_function( Function&, uint32_t );
+    void output_class( Class&, uint32_t );
+    void output_namespace( Namespace&, uint32_t );
+    void output_enum( Enum&, uint32_t);
+    void output_version_id( uint32_t vid );
+public:
+    virtual void output_tu( TranslationUnit& tu );
+    virtual ~IDLOutput() { }
+};    
+
+    }
+}
+
+#endif
+/**
+ * $Log$
+ * Revision 1.4  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.3  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.2  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/remotedescriptor.h
===================================================================
--- /tags/help/iwearrpc/include/remotedescriptor.h (revision 2216)
+++ /tags/help/iwearrpc/include/remotedescriptor.h (revision 2216)
@@ -0,0 +1,78 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_REMOTEDESCRIPTOR_H
+#define __IWREMOTE_REMOTEDESCRIPTOR_H
+
+#ifndef __IWREMOTE_PROTOCOL_H
+#include <iwremote/protocol.h>
+#endif
+
+#include <vector>
+using namespace std;
+
+namespace iwear
+{
+    namespace net
+    {
+
+/**
+ * This is a collection of data abstractly describing an object, on what host
+ * it resides and what interfaces it implements.
+ */
+struct RemoteDescriptor
+{
+    /**
+     * The actual object that is to be described
+     */
+    oid_t objectid;
+
+    /**
+     * The host on which the object resides (how it can be found is described
+     * at another place, the HostConnector)
+     */
+    hostid_t hostid;
+
+    /**
+     * A Short human readable description of the object
+     */
+    string object_name;
+
+    /**
+     * A single Object might be able to offer multiple class id intefaces (in case of inheritance)
+     */
+    vector<cid_t> class_ids;
+};
+
+	
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/remote_enums.h
===================================================================
--- /tags/help/iwearrpc/include/remote_enums.h (revision 2216)
+++ /tags/help/iwearrpc/include/remote_enums.h (revision 2216)
@@ -0,0 +1,74 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_REMOTE_ENUMS_H
+#define __IWREMOTE_REMOTE_ENUMS_H
+
+namespace iwear
+{
+    namespace net
+    {
+enum resolve_behaviour
+{
+    direct_associate,   ///< Directly associate the returned object
+    deferred_associate, ///< Dont associate the returned object, do it on first
+    ///< call (but setup internal structures so that we
+    ///< dont need to search for it)
+    oneshot_deferred,   ///< @exp like deferr, but configure for only one call then deassociate
+    num_resolve_behaviour
+};
+
+/**
+ * The higher behaviour also does a search in what the lower behaviours search.
+ * The stop behaviour may differ, so that some functions might stop if they
+ * have found something in the cache, and others only stop when everything is
+ * done.
+ */
+enum search_behaviour
+{
+    search_cache,       ///< Search in local cache only
+    search_known,       ///< Ask known hosts (those connected and in cache)
+    search_broadcast,   ///< Do a (W)LAN wide broadcast to search
+    search_p2p,         ///< Recursively search known hosts (Level is configured)
+    num_search_behaviour
+};
+
+enum rpc_type
+{
+    rpc_remote, ///< This means this connection is to some remote system e.g. via IPv4/v6, Bluetooth IrDA etc.    rpc_ipc,    ///< This type is for communication between process on localhost
+    rpc_local,  ///< This is for objects within the current process
+    rpc_external, ///< This is for plugin types...
+    num_rpc_type,
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/socketprovider.h
===================================================================
--- /tags/help/iwearrpc/include/socketprovider.h (revision 2256)
+++ /tags/help/iwearrpc/include/socketprovider.h (revision 2256)
@@ -0,0 +1,120 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_SOCKETPROVIDER_H
+#define __IWREMOTE_SOCKETPROVIDER_H
+
+#include <iwremote/callprovider.h>
+#include <iwear/socketset.h>
+#include <iwear/sslcertmanager.h>
+#include <iwear/udpconnection.h>
+#include <iwear/tcpconnection.h>
+#include <boost/intrusive_ptr.hpp>
+
+namespace iwear
+{
+    namespace net
+    {
+class SocketRemoteConnection;
+/**
+ * This class is a CallProvider for Socket based communication (IP Sockets,
+ * maybe Unix sockets later or in a seperate class, dunno how to handle them in
+ * contrast to usual IP sockets)
+ */
+class SocketProvider : public CallProvider
+{
+friend class SocketRemoteConnection;
+private:
+protected:
+    /**
+     * This set contains all the SocketRemoteConnections we have created.
+     */
+
+    TCPConnection master_tcp4;
+    TCPConnection master_tcp6;
+
+    UDPConnection master_udp4;
+    UDPConnection master_udp6;
+
+    /**
+     * Thats a socketset of all the open connections and setup sockets we have.
+     */
+    SocketSet socks;
+
+    /**
+     * The certification manager we use if ssl connections are requested.
+     */
+    SSLCertManager* sslcert;
+
+    void check_connections( void );
+
+    void check_for_incoming( void );
+    void check_existing( void );
+//    void check_preallocated( void );
+public:
+    SocketProvider( CallManager* );
+    virtual ~SocketProvider();
+
+    void _debug_add_connection( RemoteConnectionPtr );
+
+    RPCStream& get_callrpcstream( uint32_t callid, RemoteObject& );
+    RPCStream& get_retrpcstream( uint32_t callid, RemoteObject& );
+
+PH1 virtual void connected( RemoteConnectionPtr );
+
+PH1 virtual void disconnected( RemoteConnectionPtr );
+
+void search_object( RPCStream& );
+
+    /**
+     * Check for a stream thats destination is the system and return it. If
+     * after the timeout for this callprovider (e.g. listening on socket) no
+     * stream could be found, it returns NULL.
+     */
+    pair<RPCStream*,RemoteConnectionPtr> get_system_stream( double timeout );
+
+    virtual void _debug_print_state( void );
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.5  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.4  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.3  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.2  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.1  2005/06/30 18:37:30  plasmahh
+ * sync
+ *
+ */
Index: /tags/help/iwearrpc/include/cppoutput.h
===================================================================
--- /tags/help/iwearrpc/include/cppoutput.h (revision 2215)
+++ /tags/help/iwearrpc/include/cppoutput.h (revision 2215)
@@ -0,0 +1,119 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_CPPOUTPUT_H
+#define __IWREMOTE_CPPOUTPUT_H
+
+#include <iwremote/srcoutput.h>
+#include <iwremote/function.h>
+#include <iwremote/enum.h>
+
+#include <iostream>
+#include <vector>
+using namespace std;
+
+namespace iwear
+{
+    namespace net
+    {
+class Namespace;	
+class Class;
+class Declaration;
+class CppOutput : public SrcOutput
+{
+private:
+protected:
+    ostream& ccout;
+    ostream& chout;
+    ostream& scout;
+    ostream& shout;
+    
+    ostream& cmhout;
+    ostream* cmhout_p;
+
+    ostream& cmcout;
+    ostream* cmcout_p;
+
+    ostream* ccout_p;
+    ostream* chout_p;
+    ostream* scout_p;
+    ostream* shout_p;
+
+    string filebase;
+
+    protection last_prot;
+
+    void output_client( TranslationUnit& );
+    void output_server( TranslationUnit& );
+    void output_common( TranslationUnit& );
+    
+    void output_server_namespace( Namespace& ns, uint32_t indlev );
+    void output_server_class( Class& c, uint32_t indlev );
+    void output_server_classcommon( Class& c, uint32_t indlev );
+    void output_server_function( Class& c, Function& f, uint32_t indlev );
+
+    void output_client_namespace( Namespace& ns, uint32_t indlev );
+    void output_client_function( Class& c, Function& f, uint32_t indlev );
+    void output_client_class( Class& c, uint32_t indlev );
+
+    void output_common_namespace( Namespace& ns, uint32_t indlev );
+    void output_common_function( /*Class& c,*/ Function& f, uint32_t indlev );
+    void output_common_class( Class& c, uint32_t indlev );
+    void output_common_classcommon( Class& c, uint32_t indlev );
+    void output_common_enum( Enum& c, uint32_t indlev );
+    void output_common_declaration( Declaration& d, uint32_t indlev );
+
+    void output_falist( ostream& out, list<FunctionArgument>& fal );
+    void output_protection( ostream& out, protection prot, uint32_t indlev);
+    void output_derivation( ostream& o, derivation d );
+    void output_function( ostream& out, Function& f, const string& prfx); 
+
+    string get_inds( uint32_t indlev );
+
+    vector<string> indvec;
+public:
+    virtual void output_tu( TranslationUnit& tu );
+
+    CppOutput( const string& filebase );
+    virtual ~CppOutput( );
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.4  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/05 00:25:40  plasmahh
+ * iwremote stuff
+ *
+ * Revision 1.1  2004/12/02 22:41:13  plasmahh
+ * first code output generation possible (totally incomplete)
+ *
+ */
Index: /tags/help/iwearrpc/include/sptrtracker.h
===================================================================
--- /tags/help/iwearrpc/include/sptrtracker.h (revision 2215)
+++ /tags/help/iwearrpc/include/sptrtracker.h (revision 2215)
@@ -0,0 +1,151 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_SPTRTRACKER_H
+#define __IWREMOTE_SPTRTRACKER_H
+
+#ifndef __IWEAR_SPECIALPOINTER_H
+#include <iwear/specialpointer.h>
+#endif
+
+#ifndef __IWEAR_THREADLOCKED_H
+#include <iwear/threadlocked.h>
+#endif
+
+#ifndef __IWEAR_THREADLOCKER_H
+#include <iwear/threadlocker.h>
+#endif
+
+#ifndef __IWEAR_EXCEPTIONS_H
+#include <iwear/exceptions.h>
+#endif
+
+#include <set>
+using namespace std;
+
+namespace iwear
+{
+/**
+ * Every class that wants to benefit from the SPtr construct must be derived
+ * from SPtrTracker. Then it also includes the ThreadLocked capabilities so it
+ * does not need to inherit from them. Every inheritance from SPtrTracker
+ * should be virtual, in case some class has double SPtrTracker inheritance
+ * along its path.
+ * @todo Check what this construct does to multiple inheritance path classes !!
+ * @bug There is a little chance of a race condition here. Although never seen
+ * in production application code it might be possible that this leads to a
+ * crash on SMP machines.
+ */
+class SPtrTracker : public virtual ThreadLocked/*{{{*/
+{
+protected:
+    set<SpecialPointer*> SPtrMap;
+    /**
+     * Flag indicating that the destructor runs/has run. This is to reduce the
+     * possible impact of a race condition when deleting the corresponding
+     * object. However this does not fully prevent the race condition, which
+     * means that you will sometimes access already deleted memory, which might
+     * even result in an application crash.
+     */
+    bool dying : 1;
+public:
+    
+    SPtrTracker();
+    virtual ~SPtrTracker() = 0;
+
+    /**
+     * Deregisters a pointer that now does not point to this any more.
+     */
+    void deregister_sptr( SpecialPointer* );
+    /**
+     * Registeres a new Pointer, which points to this.
+     */
+    void register_sptr  ( SpecialPointer* );
+
+    /**
+     * This function does exactly nothing. Its just here to point you to the
+     * documentation of this class. You will probably made some error...
+     */
+    inline static void read_comment_on_this_function_please( void ) { }
+};/*}}}*/
+
+inline SPtrTracker::SPtrTracker()/*{{{*/
+    : dying(false)
+{
+}/*}}}*/
+
+inline void SPtrTracker::register_sptr( SpecialPointer* ptr)/*{{{*/
+{
+    ThreadLocker LockMe(&Mutex);
+
+    if ( ! dying )
+    {
+	SPtrMap.insert(ptr);
+    }
+    else
+    {
+	throw race_error("While Registering Pointer");
+    }
+
+}/*}}}*/
+
+inline void SPtrTracker::deregister_sptr( SpecialPointer* ptr)/*{{{*/
+{
+    ThreadLocker LockMe(&Mutex);
+
+    if ( ! dying )
+    {
+	SPtrMap.erase(ptr);
+    }
+    else
+    {
+	// No need to throw here since we wanted to deregister anyways...
+    }
+
+}/*}}}*/
+
+} // namespace iwear
+
+#endif
+/**
+ * $Log$
+ * Revision 1.2  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.1  2005/06/30 18:37:30  plasmahh
+ * sync
+ *
+ * Revision 1.4  2004/09/07 19:43:26  plasmahh
+ * Bug fixes and include fixes and stuff
+ *
+ * Revision 1.3  2004/08/29 11:46:16  plasmahh
+ * more working stuff
+ *
+ * Revision 1.2  2004/07/04 22:37:48  plasmahh
+ * played ;)
+ *
+ * Revision 1.1  2004/07/04 20:09:04  plasmahh
+ * added specialpointer and such stuff
+ *
+ */
Index: /tags/help/iwearrpc/include/enum.h
===================================================================
--- /tags/help/iwearrpc/include/enum.h (revision 2229)
+++ /tags/help/iwearrpc/include/enum.h (revision 2229)
@@ -0,0 +1,89 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_ENUM_H
+#define __IWREMOTE_ENUM_H
+
+#include <iwremote/statement.h>
+#include <iwremote/class.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+struct EnumDef
+{
+private:
+protected:
+public:
+    EnumDef( const string& id_, bool value_set_, int32_t value_ ) 
+	: id(id_), value_set(value_set_), value(value_) { }
+    string id;
+    bool value_set;
+    int32_t value;
+};
+/**
+ * An enum can be in both, namespace scope or class scope
+ */
+class Enum : public NamespaceItem, public ClassItem
+{
+private:
+protected:
+    list<EnumDef> enumdefs;
+public:
+    Enum( const string& id_) : ClassItem(id_) { }
+    void add_enumdef( const EnumDef& ed );
+    const list<EnumDef>& get_enumdefs( void ) const { return enumdefs; }
+    list<EnumDef>& get_enumdefs( void ) { return enumdefs; }
+
+    virtual string get_crcstring( void );
+    virtual nit_type get_namespaceitem_type( void ) { return enum_t; }
+    virtual classitem_type get_classitem_type( void ) { return enum_cit; }
+    virtual void generate_crcids( const string& );
+
+    string get_own_size( void ) { return ""; }
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.5  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.4  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/statement.h
===================================================================
--- /tags/help/iwearrpc/include/statement.h (revision 2215)
+++ /tags/help/iwearrpc/include/statement.h (revision 2215)
@@ -0,0 +1,99 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_STATEMENT_H
+#define __IWREMOTE_STATEMENT_H
+
+#include <iwear/exceptions.h>
+
+#include <list>
+using std::list;
+
+namespace iwear
+{
+    namespace net
+    {
+/*
+enum statement_type
+{
+    namespace_t,
+    class_t,
+    function_t,
+    enum_t,
+    declaration_t
+};    
+*/
+    /*
+enum protection
+{
+    public_t,
+    protected_t,
+    private_t,
+};
+*/
+/**
+ * A statement is a basic expression for code blocks. Each statement can have
+ * sub-statements which also can have substatements and so on. Statement itself
+ * is abstract so that different types can be derived from it, which itself
+ * only accept certain other kinds of statements.
+ */	
+class Statement
+{
+private:
+protected:
+    uint32_t line;
+    string file;
+public:
+    virtual ~Statement() { }
+/*
+    virtual statement_type get_type( void ) const = 0;
+    virtual void add_statement( Statement& st ) = 0;
+    const list<Statement*>& get_sub_statements( void ) const { return sub_statements; }
+    list<Statement*>& get_sub_statements( void ) { return sub_statements; }
+*/
+
+};
+
+}
+}
+
+#endif
+/**
+ * $Log$
+ * Revision 1.5  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.4  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.3  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.2  2004/12/05 00:25:40  plasmahh
+ * iwremote stuff
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/class.h
===================================================================
--- /tags/help/iwearrpc/include/class.h (revision 2229)
+++ /tags/help/iwearrpc/include/class.h (revision 2229)
@@ -0,0 +1,142 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_CLASS_H
+#define __IWREMOTE_CLASS_H
+
+#include <iwremote/statement.h>
+#include <iwremote/namespace.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+enum derivation
+{
+    public_d,
+    protected_d,
+    private_d,
+    virtual_d,
+    public_virtual_d,
+    protected_virtual_d,
+    private_virtual_d,
+};
+
+enum classitem_type
+{
+    function_cit,
+    declaration_cit,
+    class_cit,
+    enum_cit,
+    num_classitem_type
+};
+
+class Class;
+struct SubClass
+{
+private:
+protected:
+public:
+    SubClass( derivation d_t_, Class* d_class_ ) : d_t(d_t_), d_class(d_class_) { }
+    derivation d_t;
+    Class* d_class;
+};
+
+enum protection
+{
+    public_t,
+    protected_t,
+    private_t,
+    num_protection
+};
+
+class Class;
+class ClassItem: public virtual Statement
+{
+public:
+    ClassItem( const string& _id ) : id(_id) { }
+    virtual ~ClassItem() { }
+    virtual string get_crcstring(void) = 0;
+    virtual void generate_crcids( const string& ) = 0;
+    string crcs;
+    uint32_t crcid;
+    string id;
+    protection prot;
+    virtual classitem_type get_classitem_type( void ) = 0;
+    Class* my_class;
+};
+
+class Class : public NamespaceItem, public ClassItem
+{
+private:
+protected:
+public:
+    list<ClassItem*> items;
+    list<SubClass> subclasses;
+    Class( const string& _id) : ClassItem(_id) { }
+
+    uint32_t version_id;
+
+    string data_size;
+
+    void add_item( ClassItem& st );
+    void add_subclass( const SubClass& sc ) { subclasses.push_back(sc); }
+
+    /**
+     * Generates the crcids of the class and of all its functions.
+     */
+    virtual void generate_crcids( const string& );
+    virtual string get_crcstring( );
+    virtual nit_type get_namespaceitem_type( void ) { return class_t; }
+    virtual classitem_type get_classitem_type( void ) { return class_cit; }
+
+    void generate_own_size( void );
+    virtual string get_own_size( void ) { return data_size; }
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.6  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.5  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.4  2005/04/01 09:04:38  plasmahh
+ * neues für euch zum spielen
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/callmanager.h
===================================================================
--- /tags/help/iwearrpc/include/callmanager.h (revision 2256)
+++ /tags/help/iwearrpc/include/callmanager.h (revision 2256)
@@ -0,0 +1,323 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_CALLMANAGER_H
+#define __IWREMOTE_CALLMANAGER_H
+
+#include <iwremote/remoteconnection.h>
+// we need to includ remoteconnection first otherwise boost::multi_index stuff
+// does not work
+#include <iwear/utility.h>
+#include <iwear/uid.h>
+#include <iwear/service.h>
+#include <iwear/thread.h>
+#include <iwear/shmemory.h>
+#include <iwear/triple.h>
+#include <iwremote/connectiondescriptor.h>
+#include <iwremote/hostconnector.h>
+#include <iwremote/remote_enums.h>
+#include <boost/intrusive_ptr.hpp>
+#include <iwremote/securityprovider.h>
+#include <iwremote/protocol.h>
+
+#include <vector>
+using namespace std;
+
+/**
+ * Size of the SHM Segment in bytes. This should be big enough to hold most
+ * calls but small enough to not be a memory hog. We currently set it to 16kB.
+ */
+#define SHM_SIZE 16384
+namespace iwear
+{
+class ServiceManager;
+class SysVSemaphore;
+    namespace net
+    {
+
+class RemoteObject;	
+class RPCStream;
+class CallProvider;
+class RemoteDescriptor;
+class BroadCastHandle;
+class RootArtano;
+
+/**
+ * The CallManager is responsible for finding the correct object to make a
+ * remote call on and to do some basich blacklisitng and whitelisting checks.
+ * It is not responsible for host checking and accepting connections, thats the
+ * NetworkManager. The NetworkManager will also do a first protocol check if
+ * its really a call packet, or a an internal search packet.
+ */
+class CallManager : public Service, public Thread
+{
+private:
+friend class RootArtano;
+    hostid_t sysuid;
+protected:
+    RootArtano* RA;
+    /**
+     * Map the host ids to informations how to connect to them.
+     * Its a multimap because some hosts might be reachable through different
+     * mehanisms or addresses.
+     */
+    multimap<const hostid_t*, HostConnector, deref_less<const hostid_t*> > host_list;
+
+
+    /**
+     * This is a cache to see what uid/cid/name pairs a connection has
+     */
+    multimap<RemoteConnectionPtr, triple<uid,uint32_t,string> > connection_cache;
+
+    /**
+     * This is a cache to look which uid is on which (active?) RemoteConnection
+     *
+     * the stuff should be sent over to us in an associate and maybe updated on
+     * search requests etc. TODO
+     * What shall we do if the connection breaks/disconnects ?
+     */
+    map<const oid_t*, RemoteConnectionPtr, deref_less<const oid_t*> > oid_cache;
+    
+    SHMemory mm;
+    SysVSemaphore* sem;
+
+    void check_connection_pool( void );
+    void check_for_incoming( void );
+    void check_shm_pool( void );
+
+    /**
+     * Check all known CallProviders for incoming connection attempts, or
+     * re-queued system messages.
+     * @sideffect This will alter several internal structures
+     * @throw Never
+     */
+    void check_callproviders( void );
+
+    /**
+     * This processes the data which is in the incoming stream
+     * @sideffect The usage count of the passed RemoteConnection is lowered
+     */
+PH1  void process_incoming_stream( RPCStream* rpcs, RemoteConnectionPtr rc );
+
+    map<pair<RemoteConnectionPtr,chanid_t>, RPCStream* > waiting_associations;
+
+    /**
+     * A set of CallProviders which we know about and we ask for.
+     */
+    set<CallProvider*> cps;
+
+    static oid_t service_only_oid;
+
+    void object_associate( RemoteConnectionPtr rc, uint16_t chan, const hostid_t& hid, const oid_t& oid, cid_t cid );
+
+    /**
+     */
+    void check_security_provider( RemoteConnectionPtr, const hostid_t& hid, const oid_t& oid );
+
+    void send_associate_return( const hostid_t&, RemoteConnectionPtr, RemoteObject*, chanid_t );
+
+    set< SecurityProvider* > security_providers;
+
+PH1  void handle_error( RemoteConnectionPtr rc, uint32_t reason, uint16_t chan );
+
+    void finish_associate( RemoteConnectionPtr rc, RPCStream* rpcs, uint16_t chan );
+
+public:
+
+    /**
+     * Check if the packet contains any error, and if yes, throw the
+     * apporpriate exception, if not, return the type of the packet.
+     * This holds for simple protocol errors as well as several other errors
+     * like exceptions, call rejects etc.
+     */
+    uint8_t check_packet_error( RPCStream* rpcs, chanid_t );
+
+    /**
+     * This resets the stream and then advances the header information, bu
+     * returns the type at least...
+     */
+    uint8_t skip_header( RPCStream* rpcs );
+
+    /**
+     * This adds the size info to the packet, and anything that might be left.
+     */
+    void finish_packet( RPCStream* rpcs );
+
+PH1  void prepare_packet( RemoteConnectionPtr rcon, RPCStream* rpcs, chanid_t ch, uint8_t tp );
+
+    void _debug_print_state( void );
+
+    void _debug_add_host_list(const hostid_t* h, const HostConnector& hc )
+    {
+	host_list.insert(make_pair(h,hc));
+    }
+
+PH1  void add_callprovider( CallProvider* cp );
+    /**
+     * @return a channel id
+     * @warning The RemoteConnection passed might be changed to a new
+     * connection or 0, since we might need to establish a new connection.
+     */
+    chanid_t send_associate_request( RemoteConnectionPtr& rc, const oid_t& id, uint32_t crcid );
+     
+    /**
+     * Here a local _Client RemoteObject calls us with an rpcstream. We now
+     * finish the packet and send it to the _Server's RemoteHost and if the
+     * call is not marked as oneway, we also wait for returning data.
+     * In oneway case or in case of a void function, the returned result is 0,
+     * in case of failures, various exceptions may be thrown.
+     */
+PH1  RPCStream* resolve_call( RPCStream*, RemoteObject*, RemoteConnectionPtr, bool oneway );
+
+    /**
+     * When a Server side receives an call on object request, this function is
+     * called and schedules the call
+     */
+PH1  RPCStream* do_call( const oid_t&, const hostid_t&, RemoteConnectionPtr, chanid_t, uint32_t, uint32_t );
+
+    /**
+     * Return the answer to our association request...
+     * @note The current pointer on the RPCStream is on the new channel id for
+     * this connection.
+     */
+    RPCStream& get_association_return( RemoteConnectionPtr, const oid_t&, uint16_t chanid );
+
+    /**
+     * Get the connection that is actually responsible for the given object
+     * @param object id
+     */
+    RemoteConnectionPtr get_responsible_connection( const uid& ) const;
+
+    /**
+     * This searches for the host id and connects to it using a previously
+     * somehow gathered connection mechanism
+     * @param the host id
+     */
+PH1  RemoteConnectionPtr get_connection_to_host( const hostid_t& );
+    
+    /**
+     * Do a search for information about which host has this object uid
+     * available (and internally save also the information about how to reach
+     * the host, which is returned in the corresponding HostConnector)
+     */
+    multimap<RemoteDescriptor*,HostConnector> search_providing_host( const uid& o_id, search_behaviour );
+
+    virtual void Init( void );
+    virtual void Start( void );
+    virtual void Stop( void );
+    virtual void Reset( void );
+    virtual void Suspend( void );
+    virtual void Pause( void );
+    virtual void Resume( void );
+
+    virtual const string get_name( void );
+    virtual service_type get_type( void ) { return service_system; }
+
+    virtual void Run( void );
+
+    /**
+     * This function will broadcast a search or other broadcastable message to
+     * the configured hosts, and to the LAN too if this is configured.
+     * It returns a broadcast handle which can (threadsafe) be asked if the
+     * results have alrady arrived, and if they havent, give an estimate on how
+     * much is done (wont work on multihop broadcast searches and similar).
+     * This is because a broadcast might take quite a while. All the
+     * broadcastable messages act highly asynchronous, which means that we do
+     * something else and then stuff comes in and then we look what we have.
+     */
+    BroadCastHandle* broadcast( RPCStream& rpcs );
+
+    CallManager( ServiceManager*, RootArtano* );
+    virtual ~CallManager();
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.21  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.20  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.19  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.18  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.17  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ * Revision 1.16  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.15  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.14  2005/06/24 13:16:38  plasmahh
+ * Debian stinkt bis hierher
+ *
+ * Revision 1.13  2005/04/25 21:36:39  plasmahh
+ * mag ich mag ich nicht
+ *
+ * Revision 1.12  2005/04/21 19:41:57  plasmahh
+ * after work sync
+ *
+ * Revision 1.11  2005/04/20 18:08:45  plasmahh
+ * har ahr
+ *
+ * Revision 1.10  2005/04/20 14:30:48  plasmahh
+ *  new files
+ *
+ * Revision 1.9  2005/04/20 13:43:13  plasmahh
+ * merged in fixes and addups for macosx
+ *
+ * Revision 1.8  2005/04/18 20:13:58  plasmahh
+ * lm deregistration done now
+ *
+ * Revision 1.7  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.6  2005/01/21 23:34:31  plasmahh
+ * more ideas and stuff
+ *
+ * Revision 1.5  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.4  2004/12/07 11:51:56  plasmahh
+ * more testing for shm
+ *
+ * Revision 1.3  2004/12/05 00:25:40  plasmahh
+ * iwremote stuff
+ *
+ * Revision 1.2  2004/12/02 22:39:04  plasmahh
+ * first code output generation possible (totally incomplete)
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/socketconnectiondescriptor.h
===================================================================
--- /tags/help/iwearrpc/include/socketconnectiondescriptor.h (revision 2253)
+++ /tags/help/iwearrpc/include/socketconnectiondescriptor.h (revision 2253)
@@ -0,0 +1,78 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_SOCKETCONNECTIONDESCRIPTOR_H
+#define __IWREMOTE_SOCKETCONNECTIONDESCRIPTOR_H
+
+#include <iwremote/connectiondescriptor.h>
+#include <iwremote/socketremoteconnection.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+/**
+ * For a SocketRemoteConnection we dont need to do anything else for now. But
+ * for other connection types we might need to dynamically instantiate a new
+ * connection, or do some magic on them before it is beeing usable, since not
+ * all might properly support reconnect() out of the box when created (although
+ * they should, and do themselves what is then done here, so maybe we can get
+ * rid of this additional layer one day.)
+ */
+class SocketConnectionDescriptor: public ConnectionDescriptor
+{
+private:
+protected:
+public:
+    /**
+     * This returns the RemoteConnection that has been set by the connection
+     * that created this Descriptor and is responsible for it.
+     */
+//    virtual RemoteConnection* get_connection( void ) { return remote_con; }
+
+    SocketConnectionDescriptor( boost::intrusive_ptr<SocketRemoteConnection> r) : ConnectionDescriptor(r) { }
+
+    virtual ~SocketConnectionDescriptor() {}
+
+    /**
+     * We still need to specify the information returned on this
+     */
+    virtual void get_connection_features( void ) { }
+};
+
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.1  2005/09/13 23:24:22  plasmahh
+ * hope Im in sync now
+ *
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/srcoutput.h
===================================================================
--- /tags/help/iwearrpc/include/srcoutput.h (revision 2229)
+++ /tags/help/iwearrpc/include/srcoutput.h (revision 2229)
@@ -0,0 +1,59 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_SRCOUTPUT_H
+#define __IWREMOTE_SRCOUTPUT_H
+
+#include <iwremote/translationunit.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+class SrcOutput
+{
+private:
+protected:
+public:
+    virtual void output_tu( TranslationUnit& tu ) = 0;
+
+    virtual ~SrcOutput() { }
+};
+
+    }
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.3  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.2  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/remoteconnection.h
===================================================================
--- /tags/help/iwearrpc/include/remoteconnection.h (revision 2256)
+++ /tags/help/iwearrpc/include/remoteconnection.h (revision 2256)
@@ -0,0 +1,253 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_REMOTECONNECTION_H
+#define __IWREMOTE_REMOTECONNECTION_H
+
+#include <iwear/threadlocked.h>
+#include <iwear/conditional.h>
+#include <iwremote/remote_enums.h>
+#include <iwremote/protocol.h>
+
+#include <queue>
+#include <vector>
+
+#include <boost/intrusive_ptr.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/member.hpp>
+
+
+using namespace std;
+using namespace boost;
+using namespace boost::multi_index;
+
+namespace iwear
+{
+    namespace net
+    {
+
+class RemoteObject;
+class RPCStream;
+class CallProvider;
+
+typedef pair<chanid_t,RPCStream*> channel_stream;
+
+typedef multi_index_container<
+    channel_stream,
+    indexed_by<
+	sequenced<>,
+    ordered_non_unique<member<channel_stream,chanid_t,&channel_stream::first>   >
+	>
+    > stream_container;
+    }
+}
+//We need to include uid *after* this typedef, otherwise it wont compile
+#include <iwear/uid.h>
+namespace iwear
+{
+    namespace net
+    {
+/**
+ * This is a class that can wrap around different connection types to form a
+ * simple uniform interface to all possible interfaces.
+ */
+class RemoteConnection : virtual public ThreadLocked
+{
+    friend class SocketProvider;
+    friend class CallManager;
+    friend class CallProvider;
+    friend class RootArtano;
+private:
+protected:
+    friend void intrusive_ptr_add_ref( RemoteConnection* );
+    friend void intrusive_ptr_release( RemoteConnection* );
+    /**
+     * This is the uid of the host we are connected to
+     */
+    uid RemoteHost;
+
+    /**
+     * Which channels are active on this connection
+     */
+    set<chanid_t> active_channels;
+
+    /**
+     * Which channels are waiting for incoming data.
+     */
+//    set<chanid_t> waiting_channels;
+
+    map<chanid_t, RemoteObject*> object_on_channel;
+
+    set<chanid_t> preallocated_channels;
+
+    set<chanid_t> freed_channels;
+
+PH1  stream_container stream_queue;
+
+    float operation_timeout;
+
+    Conditional cond;
+    /**
+     * When we have established this connection, we are the master side and are
+     * responsible for channel allocation.
+     */
+    bool master_side;
+
+    bool is_sequenced;
+
+    CallProvider* prov;
+
+    /**
+     * Get the next sequence number to be sent
+     */
+    uint32_t next_sequence( void );
+
+    /**
+     * Say that we have received this sequence nr.
+     */
+    void got_sequence( uint32_t );
+
+
+    bool has_sequence( uint8_t flgs ) const { return (flgs & MSG_FLAG_SEQ); }
+    
+    bool has_ssl( uint8_t flgs ) const { return (flgs & MSG_FLAG_SSL); }
+
+    bool has_gzip( uint8_t flgs ) const { return (flgs & MSG_FLAG_GZIP); }
+
+    bool flags_valid( uint8_t flgs ) const { return flgs == (flgs & (MSG_FLAG_SEQ | MSG_FLAG_SSL | MSG_FLAG_GZIP)); }
+
+
+    int8_t get_actual_flags( void ) { return actual_flags; }
+
+    int8_t actual_flags;
+
+    uint32_t act_seq;
+
+    uint32_t refcount;
+
+public:
+    RemoteObject* get_object( chanid_t );
+
+    const set<chanid_t>& get_preallocated_channels( void ) const { return preallocated_channels; }
+
+    virtual RPCStream* get_stream( uint32_t est ) = 0;
+
+    virtual void recycle_stream( RPCStream* ) = 0;
+    /** 
+     * Sends a simple error msg to a specified channel
+     */
+    void send_simple_error( uint32_t rsn, chanid_t );
+
+    void handle_error( const protocol_error& );
+
+    bool is_master( void ) const { return master_side; }
+    RemoteConnection( CallProvider* cp, bool ms, float oto);
+
+    CallProvider* get_callprovider( void ) { return prov; }
+    Conditional& get_conditional( void ) { return cond; }
+
+    int wait_for_channel( uint16_t chan );
+
+    virtual ~RemoteConnection();
+    const uid& get_uid( void ) const { return RemoteHost; }
+    virtual rpc_type get_type( void ) const = 0;
+
+    /**
+     * This function extracts the buffer from the given rpcstream and sends it
+     * over the connection. The stream must be suitable for the given
+     * connection type, the responsibility for this lies at the caller, we will
+     * here send everything over the connection.
+     */
+    virtual void send_rpcpacket( const RPCStream* spc ) = 0;
+
+    virtual bool is_connected( void ) const = 0;
+
+    virtual bool reconnect( void ) = 0;
+
+    virtual void disconnect( void ) = 0;
+
+    virtual void set_connection_policy( void ) = 0;
+
+    /**
+     * Receives a packet and calls the set_buffer of the corresponding
+     * RPCStream. The buffer will then belong to the RPCStream so this is
+     * responsible for proper memory deletion.
+     */
+PH1  virtual bool receive_rpcpacket( RPCStream& spc, chanid_t channel ) = 0;
+
+    virtual bool has_ipaddress( void ) const = 0;
+    virtual string get_ipaddress( void ) const = 0;
+
+    virtual bool has_sslkey( void ) const = 0;
+    virtual bool get_sslkey( void ) const = 0;
+
+
+    /**
+     * The Channel Preallocation will lock everything, change the maps and then
+     * unlock. From this on the channel cannot be used by anyone else. We will
+     * use the channel to setup a real allocation then
+     */
+PH1  chanid_t preallocate_channel( void );
+
+    /**
+     * If were slave-side we preallocate a channel when we get a first
+     * associate request. This is checked against all pre-allocated and
+     * associated channels
+     */
+PH1  void preallocate_channel( chanid_t );
+
+    /**
+     * Here we really allocate a previously pre-allocated channel
+     */
+PH1  void allocate_channel( RemoteObject*, chanid_t );
+    
+};
+
+typedef boost::intrusive_ptr<RemoteConnection> RemoteConnectionPtr;
+
+inline void intrusive_ptr_release( RemoteConnection* rc )
+{
+    ThreadLocker tl(rc->Mutex);
+    --(rc->refcount);
+    if( rc->refcount == 0 )
+    {
+	delete rc;
+    }
+}
+
+inline void intrusive_ptr_add_ref( RemoteConnection* rc )
+{
+    ThreadLocker tl(rc->Mutex);
+    ++(rc->refcount);
+    // Do we need to do more ?
+}
+
+}
+}
+
+#endif
+/**
+ */
Index: /tags/help/iwearrpc/include/scheduler.h
===================================================================
--- /tags/help/iwearrpc/include/scheduler.h (revision 2216)
+++ /tags/help/iwearrpc/include/scheduler.h (revision 2216)
@@ -0,0 +1,61 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ _H
+#define __ _H
+
+namespace iwear
+{
+    namespace net
+    {
+
+/**
+ * This class schedules calls among the available threads, and if necssary
+ * spawns new threads.
+ * 
+TODO
+
+Configurable number of spare-threads which are minimally hold
+Configurable number of max-threads, maximumg which the system should execute
+(including all other threads)
+Configurable (?) way of how idle-threads decay and are spawned (burst calls)
+*/
+class Scheduler
+{
+private:
+protected:
+public:
+    void schedule_call( RemoteObject&, RPCStream& rpcs);
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/classprovider.h
===================================================================
--- /tags/help/iwearrpc/include/classprovider.h (revision 2252)
+++ /tags/help/iwearrpc/include/classprovider.h (revision 2252)
@@ -0,0 +1,94 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_CLASSPROVIDER_H
+#define __IWREMOTE_CLASSPROVIDER_H
+
+#include <iwremote/protocol.h>
+#include <iwremote/rootartano.h>
+
+extern "C"
+{
+#include <stdint.h>
+}
+
+namespace iwear
+{
+    namespace net
+    {
+class RemoteObject;
+/**
+ * The class provider is a class that is intended to beeing instantiated
+ * statically so that its constructor will fill in information needed by the RootArtano.
+ *
+ * It is mainly to provide a mechanism, that when we have a classid, we can
+ * properly instantiate a Client class. In the future this might be usefuly for
+ * dynamic server class instantiation as well, in case just a classid is requested
+ *
+ * @exp This is experimental and will change rapidly and heavily
+ */
+class ClassProvider
+{
+private:
+protected:
+    cid_t cid;
+public:
+    ClassProvider( cid_t _cid, RemoteObject* (*fp) (), void (*init)() )
+        : cid(_cid)
+    {
+	RootArtano::provide_client(_cid, fp );
+	if( init != 0 )
+	{
+	    init(); // Call the static initialization of the class (experimental)
+	}
+    }
+
+    virtual ~ClassProvider()
+    {
+	RootArtano::remove_client(cid);
+    }
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.5  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.4  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.3  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.2  2005/04/25 07:49:34  plasmahh
+ * gradegebogen, alle module müssen das gleiche haben
+ *
+ * Revision 1.1  2005/04/20 14:30:48  plasmahh
+ *  new files
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/type.h
===================================================================
--- /tags/help/iwearrpc/include/type.h (revision 2256)
+++ /tags/help/iwearrpc/include/type.h (revision 2256)
@@ -0,0 +1,124 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_TYPE_H
+#define __IWREMOTE_TYPE_H
+
+#include <string>
+using namespace std;
+
+namespace iwear
+{
+    namespace net
+    {
+/**
+ * denotes a type specifier, so the one that might be before a variable or
+ * function argument declaration
+ */
+struct Type
+{
+    /**
+     * the idntifier, like uint32_t or string or a user type
+     */
+PH1  string id;
+
+    /**
+     * If this is a reference type, which in fact is a reference to an
+     * associated object, so as a parameter its a uid on remote passing
+     */
+PH1  bool reference;
+
+    /**
+     * returns true if its a builtin pod type (with RPCStream primitives)
+     */
+PH1  bool builtin( void );
+
+    /**
+     * returns the size of the type if available without an actual object.
+     * For things like strings, containers and user objects its not available
+     * without an actual object.
+     */
+PH1  virtual string get_static_size( void );
+
+    /**
+     * A non-pod type needs to return the dynamic size of the object, to be
+     * determined at runtime, if its not such a type the static size is returned.
+     * @param var is the name of the variable to use to get the size from
+     */
+PH1  virtual string get_dynamic_size( const string& var );
+
+PH1  Type( const string& _id, bool ref )
+	: id(_id), reference(ref) { }
+
+PH1  virtual ~Type() { }
+};
+
+/**
+ * we support certain container types like lists, sets etc.
+ * This type does not contribute to the crcid, since when iterating through the
+ * container, it will come in the same order into the other container, no
+ * matter which one it is...
+ */
+struct ContainerType: public Type
+{
+    /**
+     * the container type, whats allowed is (the parser will have checked it):
+     * set, list, vector, queue
+     * of course only of supported Types
+     */
+PH1  string container;
+
+    /**
+     * the type of the to-be contained data
+     */
+PH1  Type* id;
+
+    /**
+     * returns an empty string, since we cannot determine the static size of a
+     * container, there is nothing such
+     */
+PH1  virtual string get_static_size( void );
+    /**
+     * returns the code to determine the static size. The data is added to the
+     * variable sz
+     */
+PH1  virtual string get_dynamic_size( const string& var );
+
+PH1  ContainerType( const string& cont, Type* _id, const string& did, bool ref )
+	: Type(did,ref), container(cont), id(_id) { }
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.2  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.1  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/securityprovider.h
===================================================================
--- /tags/help/iwearrpc/include/securityprovider.h (revision 2252)
+++ /tags/help/iwearrpc/include/securityprovider.h (revision 2252)
@@ -0,0 +1,69 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_SECURITYPROVIDER_H
+#define __IWREMOTE_SECURITYPROVIDER_H
+
+#include <iwremote/remoteconnection.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+class SecurityProvider
+{
+private:
+protected:
+public:
+    SecurityProvider() { }
+    virtual ~SecurityProvider() { }
+
+    /**
+     * This just checks the connection
+     */
+    virtual bool check_connection( RemoteConnectionPtr rcon ) = 0;
+
+    /**
+     * Checks the host, returns if the host is allowed to execute commands on
+     * us or not.
+     */
+    virtual bool check_host( RemoteConnectionPtr rcon, const hostid_t& hid ) = 0;
+
+    virtual bool check_object( RemoteConnectionPtr rcon, const hostid_t& hid, const oid_t& oid ) = 0;
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.2  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/function.h
===================================================================
--- /tags/help/iwearrpc/include/function.h (revision 2256)
+++ /tags/help/iwearrpc/include/function.h (revision 2256)
@@ -0,0 +1,171 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_FUNCTION_H
+#define __IWREMOTE_FUNCTION_H
+
+#include <iwremote/statement.h>
+#include <string>
+#include <iwremote/class.h>
+#include <iwremote/type.h>
+using std::string;
+
+namespace iwear
+{
+    namespace net
+    {
+
+enum argtype
+{
+    in_t,
+    out_t,
+    inout_t
+};
+
+struct FunctionArgument
+{
+    /**
+     * The type of the parameter
+     */
+PH1  Type* type;
+
+    /**
+     * The in/out modifier
+     */
+PH1  argtype mytype;
+
+    /**
+     * The actual name of the parameter
+     */
+PH1  string id;
+
+PH1  FunctionArgument( Type* type_, argtype mytype_, const string& id_) 
+	: type(type_), mytype(mytype_), id(id_) { }
+
+PH1  string get_crcstring( void );
+};
+
+class Function : public ClassItem
+{
+private:
+protected:
+public:
+    /**
+     * In same order as the function parameters
+     */
+PH1  list<FunctionArgument> arguments;
+
+    /**
+     * we only need one ;)
+     */
+PH1  FunctionArgument return_type;
+
+    bool is_const;
+
+    /**
+     * If this is a one-way function we handle it specially when calling
+     */
+PH1  bool is_oneway;
+
+    /**
+     * if its cached we implement a cache and check it frequently 
+     */
+PH1  bool is_cached;
+//    uint32_t crcid;
+    /**
+     * 
+     */    
+PH1  uint32_t version_id;
+
+    /**
+     * if this is a function that implements another interface version, this is
+     * the real function on the server host do call
+     */
+PH1  string versioncall;
+
+    Function( const FunctionArgument& rett, const string& _id, bool con, bool one, bool cac, uint32_t vid, const string& vc = "" ) 
+	: ClassItem(_id), return_type(rett), is_const(con), is_oneway(one), is_cached(cac), version_id(vid), versioncall(vc) { }
+
+    /**
+     * return the code to determine the size of outgoing data (this the return
+     * type and the amount of out data...
+     */
+PH1  string get_outsize( void );
+
+    /**
+     * this returns the code to determine the amount of data needed to bass to
+     * the call (it does not include data that just goes out as this is
+     * tempporarily generated locally)
+     */
+PH1  string get_insize( void );
+
+PH1  void add_argument( const FunctionArgument& fa ) { arguments.push_back(fa); }
+
+    /**
+     * Assembles and returns a uinque string that will be used for generating
+     * the crcid
+     */
+PH1  virtual string get_crcstring( void );
+
+    /**
+     * generate the crcid number of this function. It will include the
+     * arguments, return type and type of the function, and so on
+     * @param the class string so same signatures have different crcids
+     */
+PH1  virtual void generate_crcids(const string&);
+    
+PH1  virtual classitem_type get_classitem_type( void ) { return function_cit; }
+};
+
+}
+}
+
+#endif
+/**
+ * $Log$
+ * Revision 1.8  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.7  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.6  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.5  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.4  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.3  2004/12/05 00:25:40  plasmahh
+ * iwremote stuff
+ *
+ * Revision 1.2  2004/12/02 22:39:04  plasmahh
+ * first code output generation possible (totally incomplete)
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/declaration.h
===================================================================
--- /tags/help/iwearrpc/include/declaration.h (revision 2256)
+++ /tags/help/iwearrpc/include/declaration.h (revision 2256)
@@ -0,0 +1,90 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_DECLARATION_H
+#define __IWREMOTE_DECLARATION_H
+
+#ifndef __IWREMOTE_STATEMENT_H
+#include <iwremote/statement.h>
+#endif
+
+#include <iwremote/class.h>
+#include <iwremote/type.h>
+
+namespace iwear
+{
+    namespace net
+    {
+/**
+ * Declarations can only be in classes, and contain no sub-statements.
+ */
+class Declaration : public ClassItem
+{
+private:
+protected:
+public:
+PH1  bool readonly;
+
+PH1  Type* type;
+
+///PH1  string id;
+
+PH1  Declaration( Type* type_, const string& id_, bool readonly_) 
+	: ClassItem(id_), readonly(readonly_), type(type_) { }
+
+PH1  virtual string get_crcstring( void );
+
+    virtual classitem_type get_classitem_type( void ) { return declaration_cit; }
+
+PH1  virtual void generate_crcids( const string& );
+
+    virtual string get_own_size( void );
+};
+
+}
+}
+
+#endif
+
+/**
+ * $Log$
+ * Revision 1.6  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.5  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.4  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/nullstream.h
===================================================================
--- /tags/help/iwearrpc/include/nullstream.h (revision 2215)
+++ /tags/help/iwearrpc/include/nullstream.h (revision 2215)
@@ -0,0 +1,93 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_NULLSTREAM_H
+#define __IWREMOTE_NULLSTREAM_H
+
+#include <iwremote/rpcstream.h>
+
+namespace iwear
+{
+    namespace net
+    {
+/**
+ * This class implements the interface for RPCStream objects as a NULL stream
+ * objet, e.g. just copying the data. It can be used for local-intra-process
+ * shortcutting.
+ */
+class NULLStream : public RPCStream
+{
+private:
+protected:
+    void* stream;
+public:
+    NULLStream( size_t );
+    virtual ~NULLStream();
+    /**
+     * Parses the next stream object and returns it as bool. Throws exception
+     * when failing.
+     */
+    virtual bool get_bool( void );
+    virtual double get_double( void );
+    virtual float get_float( void );
+    virtual int get_int( void );
+    virtual long get_long( void );
+    virtual string get_string( void );
+    virtual uid get_uid( void );
+
+    virtual void put_bool( bool );
+    virtual void put_double( double );
+    virtual void put_float( float );
+    virtual void put_int( int );
+    virtual void put_long( long );
+    virtual void put_string( const string& );
+    virtual void put_uid( const uid& );
+
+    virtual std::pair<char *, uint32_t> get_buffer( void );
+    virtual void set_buffer( char*, uint32_t );
+
+    virtual size_t max_size( void );
+    virtual void resize( size_t );
+
+
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.3  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.2  2005/01/21 23:34:31  plasmahh
+ * more ideas and stuff
+ *
+ * Revision 1.1  2004/11/30 12:53:30  plasmahh
+ * more stuff to go...
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/callprovider.h
===================================================================
--- /tags/help/iwearrpc/include/callprovider.h (revision 2256)
+++ /tags/help/iwearrpc/include/callprovider.h (revision 2256)
@@ -0,0 +1,145 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_CALLPROVIDER_H
+#define __IWREMOTE_CALLPROVIDER_H
+
+#include <iwremote/remoteconnection.h>
+// we need to include remoteconnection first otherwise boost::multi_index would
+// not work
+#include <iwear/utility.h>
+#include <iwear/uid.h>
+#include <iwear/shmemory.h>
+#include <iwear/debugstream.h>
+
+#include <queue>
+using namespace std;
+
+namespace iwear
+{
+    namespace net
+    {
+class RPCStream;	
+class RemoteObject;
+class CallManager;
+/**
+ * A Call Provider is a base class for (not only plugins) that provide some
+ * data transfer mechanisms. Each RemoteObject on the Client Side will have
+ * some CallProvider that provides the necessary mechanisms for it. At
+ * Connection Discovery Phase, or at Reconnection Phase this CallProvider will
+ * be (re)set to reflect a new connection method. It might later be embedded
+ * into some connection descriptor pointer that the RemoteObject will hold.
+ *
+ * A Call Provider will provide the necessary rpcstreams to do a call. This
+ * means that either for every connection (stream)type a single CallProvider is
+ * needed or that the CallProvider knows how to distinguish.
+ *
+ * @todo TODO Maybe create the ConnectionDescriptor as a polymorphic class we
+ * can *upcast* (brr, ugly) and use then ?
+ */
+class CallProvider
+{
+    //XXX Need to somehow get rid of this !!
+friend class SocketRemoteConnection;
+private:
+protected:
+    CallManager* cman;
+    /**
+     * This is a queue containing all the System messages that were received by
+     * other threads. We should first empty this queue and then receive new
+     * requests.
+     */
+PH1  queue<pair<RPCStream*,RemoteConnectionPtr> > msgq;
+
+PH1  set<RemoteConnectionPtr > remote_connections;
+
+PH1  void interpret_channelstream( chanid_t chan, RPCStream* rpcs, RemoteConnectionPtr rc );
+
+PH1  void do_call( const oid_t& oid, const hostid_t& hid, RemoteConnectionPtr rcon,
+	    RPCStream*, chanid_t chan, uint32_t func, uint32_t fver );
+
+PH1  void insert_system( RPCStream*, RemoteConnectionPtr );
+public:
+
+    /**
+     * This function is called *from* the RemoteConnection itself to tell the
+     * callprovider it has been connected.
+     */
+PH1 virtual void connected( RemoteConnectionPtr ) = 0;    
+
+PH1 virtual void disconnected( RemoteConnectionPtr ) = 0;    
+
+    CallProvider( CallManager* );
+    virtual ~CallProvider();
+
+    virtual void check_channels( void );
+    virtual RPCStream& get_callrpcstream( uint32_t callid, RemoteObject& ) = 0;
+    virtual RPCStream& get_retrpcstream( uint32_t callid, RemoteObject& ) = 0;
+
+    virtual void search_object( RPCStream& ) = 0;
+
+
+    /**
+     * Check for a stream thats destination is the system and return it. If
+     * after the timeout for this callprovider (e.g. listening on socket) no
+     * stream could be found, it returns NULL.
+     * @note this is the function that triggers the look after all the
+     * connections, like accepting incoming connections, reading out of other
+     * connections into local buffers etc. So make sure you call it frequently.
+     */
+    virtual pair<RPCStream*,RemoteConnectionPtr> get_system_stream( double timeout ) = 0;
+
+    virtual void _debug_print_state( void ) { d_dbg << "No state available" << endl; }
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.8  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.7  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.6  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.5  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.4  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.3  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.2  2005/04/20 14:30:48  plasmahh
+ *  new files
+ *
+ * Revision 1.1  2005/04/20 13:43:13  plasmahh
+ * merged in fixes and addups for macosx
+ *
+ */
Index: /tags/help/iwearrpc/include/hostconnector.h
===================================================================
--- /tags/help/iwearrpc/include/hostconnector.h (revision 2216)
+++ /tags/help/iwearrpc/include/hostconnector.h (revision 2216)
@@ -0,0 +1,59 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_HOSTCONNECTOR_H
+#define __IWREMOTE_HOSTCONNECTOR_H
+
+#include <iwremote/protocol.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+class ConnectionDescriptor;
+/**
+ * This holds the description of a host uid and the way how to connect to it
+ */
+struct HostConnector
+{
+    const hostid_t* hostid;
+    /**
+     * This class is virtual and will contain everything necessary to connect
+     * to the host
+     */
+    ConnectionDescriptor* condis;
+    HostConnector( const hostid_t* u, ConnectionDescriptor* c ) : hostid(u), condis(c) { }
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/rootartano.h
===================================================================
--- /tags/help/iwearrpc/include/rootartano.h (revision 2256)
+++ /tags/help/iwearrpc/include/rootartano.h (revision 2256)
@@ -0,0 +1,229 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_ROOTARTANO_H
+#define __IWREMOTE_ROOTARTANO_H
+
+#include <iwremote/remoteconnection.h>
+// we need to include remoteconnection first otherwise boost::multi_index would
+// not work
+#include <iwear/uid.h>
+#include <iwremote/protocol.h>
+#include <iwremote/remotedescriptor.h>
+#include <iwremote/remote_enums.h>
+#include <boost/intrusive_ptr.hpp>
+
+#include <vector>
+using namespace std;
+
+namespace iwear {
+class ServiceManager;
+    namespace net {
+
+// some forward declarations
+class CallManager;
+class RemoteObject;
+class RemoteConnection;
+class RPCStream;
+
+/**
+ * The RootArtano is the key class from which people will ask for
+ * remoteobjects, and pass their remoteobjects or references to it to be
+ * destroyed. They should never need to interface with the CallManager or
+ * CallProviders or similar classes.
+ * It will setup the CallManager as well as everything thats needed for the
+ * others, like SSL configuration locations etc. The configuration itself will
+ * of course be read by the classes themselves.
+ * @note We *need* some myth in the core of a program. Artano is elvish for
+ * "highest blacksmith", so this class can be seen as the one and only master
+ * class that will create objects.
+ */
+class RootArtano : public ThreadLocked
+{
+friend class CallManager;
+private:
+protected:
+    /**
+     * This is the CallManager we do all our calls on.
+     */
+    CallManager* cman;
+
+    /**
+     * This is the cache of currently existing and associated objects we have.
+     */
+    map<const oid_t*,RemoteObject*,deref_less<const oid_t*> > rmos;
+
+    /**
+     * Here we map the information on how to find a given oid_t, means on which
+     * host. At another place we need to save how to get to this host.
+     */
+    map<const oid_t*,RemoteDescriptor*,deref_less<const oid_t*> > uid_rmt;
+
+
+    /**
+     * Here we look for the local-server RemoteObjects which are created in the
+     * system, and might be offered to outside systems.
+     */
+    map<const oid_t*, RemoteObject*,deref_less<const oid_t*> > oid_object;
+
+    /**
+     * searches in oid_object for a given object locally, with this uid
+     * (shortcutting)
+     */
+    RemoteObject* get_object( const oid_t& oid);
+    
+    /**
+     * This map is a lookup for the client side so that we can ask for a cid,
+     * and if its associatable we get the proper client class returned.
+     */
+    static map<cid_t,RemoteObject*(*)()>* cid_inst;
+
+    /**
+     * This is a multimap storing multiple possible instantiations for
+     * dynamically allocatable servers
+     */
+    static multimap<cid_t,RemoteObject*(*)()>* server_inst;
+    void send_deassociate( RemoteConnectionPtr rc, RemoteObject* ro );
+
+    /**
+     * @warning After a call to this the RemoteConnection might not be the
+     * responsible for this object any more, or maybe even completely invalid
+     * or deleted !  So, don't use it any more then.
+     */
+    RemoteObject* associate_on_connection( RemoteConnectionPtr rc, const oid_t& id, resolve_behaviour rb );
+    RPCStream& get_search_packet( const uid& id, uint32_t hopcount );
+    RPCStream& get_search_packet( uint32_t crcid, uint32_t hopcount );
+
+    RemoteObject* create_instance( cid_t cid );
+public:
+    /**
+     * Remove the server instantiator by its function...
+     */
+    static void remove_server( RemoteObject* fp() );
+
+    static void remove_client( cid_t cid );
+
+
+    
+    static void provide_client( cid_t cid, RemoteObject* fp() );
+
+    /**
+     * Provide a dynamically allocatable server which might implement multiple
+     * cids (e.g. due to inheritance)
+     */
+    static void provide_server( vector<cid_t>& cids, RemoteObject* fp() );
+    
+
+    void register_object( const oid_t& oid, RemoteObject* ro );
+
+    /**
+     * @warning This is only for debugging and should never be used
+     */
+    void _debug_add_uid_rmt( const oid_t* u, RemoteDescriptor* r )
+    {
+	uid_rmt.insert(make_pair(u,r));
+    }
+
+    RootArtano( ServiceManager* sm );
+    virtual ~RootArtano();
+    CallManager& get_callmanager( void );
+    const CallManager& get_callmanager( void ) const;
+
+    /**
+     * Should never be called multiple times
+     */
+    void Init( void );
+    /**
+     * Here we search for and establish a connection with an object on a
+     * possibly remote host, with the uid of this object. Everytime an object
+     * is resolved, for destruction it must be issued to the recycle()
+     * function. If an object has be resolved twice, it must be recycled twice
+     * for final destruction etc.
+     * @note This will use a caching mechanism for the search, so a subsequent
+     * resolve for the same uid will prbably not cause any traffic other than
+     * the association.
+     * @note the resolve_behaviour is only a strict-hint. Means that if you
+     * want a deferred object, and the object is already associated within the
+     * system, it will be as if direct_associate was specified
+     *
+     * The search behaviour is the same as the search since, esentially we
+     * might need to do a search the same way (but for other parameters)
+     * Per default we try really hard to find the object, but use the first
+     * available found.
+     */
+    RemoteObject* resolve( const uid&, resolve_behaviour rb = direct_associate, 
+	    search_behaviour sb = search_p2p );
+
+   /**
+     * Search for a class ID and return a list of pairs with the objects and a
+     * short description that offer this service.
+     */
+    set<RemoteDescriptor* > search( uint32_t cid, search_behaviour = search_cache );
+
+    /**
+     * The same as the search above, with the difference that we only search on
+     * a specific host, which we specify by its uid.
+     * @note Therefore we dont have to specify the behaviour since we know whom
+     * to ask
+     */
+    set<RemoteDescriptor* > search( uint32_t cid, const uid& );
+
+    /**
+     * This destroys the object. It checks a reference count on the object
+     */
+    void recycle( RemoteObject* );
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.10  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.9  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.8  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.7  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.6  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.5  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.4  2005/04/25 07:49:34  plasmahh
+ * gradegebogen, alle module müssen das gleiche haben
+ *
+ * Revision 1.3  2005/04/21 19:41:57  plasmahh
+ * after work sync
+ *
+ * Revision 1.2  2005/04/20 18:08:45  plasmahh
+ * har ahr
+ */
Index: /tags/help/iwearrpc/include/namespace.h
===================================================================
--- /tags/help/iwearrpc/include/namespace.h (revision 2215)
+++ /tags/help/iwearrpc/include/namespace.h (revision 2215)
@@ -0,0 +1,86 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_NAMESPACE_H
+#define __IWREMOTE_NAMESPACE_H
+
+#include <iwremote/statement.h>
+namespace iwear
+{
+    namespace net
+    {
+
+enum nit_type 
+{
+    namespace_t,
+    class_t,
+    enum_t,
+    num_nit_type
+};
+
+/**
+ * Item that can be within a namespace
+ */	
+class NamespaceItem: public virtual Statement
+{
+public:
+    virtual ~NamespaceItem() { }
+    virtual nit_type get_namespaceitem_type( void ) = 0;
+};    
+/**
+ * A Namespace can hold classes and enums.
+ */
+class Namespace : public NamespaceItem
+{
+private:
+protected:
+public:
+    list<NamespaceItem*> items;
+    string id;
+    Namespace( const string& _id ) : id(_id) { }
+    virtual ~Namespace() { }
+
+    void add_item( NamespaceItem& ni );
+    virtual string get_crcstring( void );
+    virtual nit_type get_namespaceitem_type( void ) { return namespace_t; }
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.4  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/translationunit.h
===================================================================
--- /tags/help/iwearrpc/include/translationunit.h (revision 2215)
+++ /tags/help/iwearrpc/include/translationunit.h (revision 2215)
@@ -0,0 +1,61 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_TRANSLATIONUNIT_H
+#define __IWREMOTE_TRANSLATIONUNIT_H
+
+#include <iwremote/namespace.h>
+namespace iwear
+{
+    namespace net
+    {
+
+class TranslationUnit
+{
+private:
+protected:
+    list<Namespace*> namespaces;
+public:
+    const list<Namespace*>& get_namespacs( void ) const { return namespaces; }
+    list<Namespace*>& get_namespaces( void ) { return namespaces; }
+
+    void add_namespace( Namespace& st );
+};
+
+    }
+}
+
+#endif
+/**
+ * $Log$
+ * Revision 1.3  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.2  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/connectiondescriptor.h
===================================================================
--- /tags/help/iwearrpc/include/connectiondescriptor.h (revision 2256)
+++ /tags/help/iwearrpc/include/connectiondescriptor.h (revision 2256)
@@ -0,0 +1,81 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_CONNECTIONDESCRIPTOR_H
+#define __IWREMOTE_CONNECTIONDESCRIPTOR_H
+
+#include <boost/intrusive_ptr.hpp>
+
+namespace iwear
+{
+    namespace net
+    {
+class RemoteConnection;
+
+/**
+ * A ConnectionDescriptor is a class which holds the information how to connect
+ * to a specific host. For more information on how the class should be used,
+ * @see SocketConnectionDescriptor.
+ */
+class ConnectionDescriptor
+{
+private:
+protected:
+    //FIXME this needs to be replaced by just some data to connect !
+    RemoteConnectionPtr remote_con;
+public:
+    /**
+     * This returns the RemoteConnection that has been set by the connection
+     * that created this Descriptor and is responsible for it.
+     */
+    virtual RemoteConnectionPtr get_connection( void ) { return remote_con; }
+
+    ConnectionDescriptor( RemoteConnectionPtr r) : remote_con(r) { }
+
+    virtual ~ConnectionDescriptor() {}
+
+    /**
+     * This returns a set of features of the connection, like if it supports
+     * ssl, or how fast it could be etc., this is a big fat @todo TODO
+     */
+    virtual void get_connection_features( void ) = 0;
+};
+
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.3  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.2  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/rpcstream.h
===================================================================
--- /tags/help/iwearrpc/include/rpcstream.h (revision 2256)
+++ /tags/help/iwearrpc/include/rpcstream.h (revision 2256)
@@ -0,0 +1,213 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_RPCSTREAM_H
+#define __IWREMOTE_RPCSTREAM_H
+
+#ifndef __IWEAR_UID_H
+#include <iwear/uid.h>
+#endif
+
+#include <iwremote/protocol.h>
+
+#include <string>
+#include <utility>
+using std::string;
+
+void sorry_this_return_type_is_not_defined();
+namespace iwear
+{
+    namespace net
+    {
+/**
+ * This class is base class for all classes that want to implement some RPC
+ * data streaming structures with implicit typing.
+ *
+ * The new get/set functions reflect the size of the data to make it clearer,
+ * since the "items" in the streams need to have fixed data since they might
+ * need to be reassembled on a system where the size of a basic type like "int"
+ * or "long" is another.
+ */
+class RPCStream
+{
+private:
+protected:
+public:
+PH1  virtual ~RPCStream() {}
+    /**
+     * Parses the next stream object and returns it as bool. Throws exception
+     * when failing.
+     */
+PH1  virtual bool get_bool( void ) = 0;
+
+PH1  virtual int8_t get_int8_t( void ) = 0;
+PH1  virtual uint8_t get_uint8_t( void ) = 0;
+
+PH1  virtual int16_t get_int16_t( void ) = 0;
+PH1  virtual uint16_t get_uint16_t( void ) = 0;
+
+PH1  virtual int32_t get_int32_t( void ) = 0;
+PH1  virtual uint32_t get_uint32_t( void ) = 0;
+
+PH1  virtual int64_t get_int64_t( void ) = 0;
+PH1  virtual uint64_t get_uint64_t( void ) = 0;
+
+PH1  virtual double get_double( void ) = 0;
+PH1  virtual float get_float( void ) = 0;
+
+PH1  virtual string get_string( void ) = 0;
+PH1  virtual uid get_uid( void ) = 0;
+
+PH1  virtual void put_bool( bool ) = 0;
+
+PH1  virtual void put_int8_t( int8_t ) = 0;
+PH1  virtual void put_uint8_t( uint8_t ) = 0;
+
+PH1  virtual void put_int16_t( int16_t ) = 0;
+PH1  virtual void put_uint16_t( uint16_t ) = 0;
+
+PH1  virtual void put_int32_t( int32_t ) = 0;
+PH1  virtual void put_uint32_t( uint32_t ) = 0;
+
+PH1  virtual void put_int64_t( int64_t ) = 0;
+PH1  virtual void put_uint64_t( uint64_t ) = 0;
+
+PH1  virtual void put_double( double ) = 0;
+PH1  virtual void put_float( float ) = 0;
+
+PH1  virtual void put_string( const string& ) = 0;
+PH1  virtual void put_uid( const uid& ) = 0;
+
+
+PH1  virtual std::pair<char *, uint32_t> get_buffer( void ) = 0;
+
+PH1  virtual std::pair<const char *, uint32_t> get_buffer( void ) const= 0;
+
+    /**
+     * This sets the buffer, means the stream may use the buffer.
+     */
+PH1  virtual void set_buffer( char*, uint32_t ) = 0;
+
+    /**
+     * This replaces the internal buffer. The buffer must be allocated with new
+     * and will be deleted by the stream.
+     */
+PH1  virtual void replace_buffer( char*, uint32_t ) = 0;
+
+    /**
+     * This replaces the current buffer with the one out of the providing
+     * stream, and the providing streams buffer will be emptied.
+     */
+PH1  virtual void replace( RPCStream& ) = 0;
+
+    /**
+     * Returns the actual amount of data readable. Its in "data read units"
+     * means in the amount of smallest available data units. If the stream
+     * contains explicit type or size restrictions, this will be included too.
+     * So different streams might return different values for the same data
+     * (XML vs. binary)
+     */
+PH1  virtual uint32_t data( void ) = 0;
+
+PH1  virtual size_t max_size( void ) = 0;
+PH1  virtual void resize( size_t ) = 0;
+
+PH1  template<class T> T get( void );
+
+    /**
+     * This resets the streams pointer to the beginning, it does not empty it !
+     * (This is for moving around in the packet, not for clearing it)
+     */
+PH1  virtual void reset( void ) = 0;
+
+    /**
+     * This function is beeing called on a freshly created rpcstream when it is
+     * to be used for a outgoing call
+     */
+PH1  virtual void start_call( cid_t cid ) { }
+
+    /**
+     * Ends a call started with start_call
+     */
+PH1  virtual void end_call( void ) { }
+};
+
+#define TEMPL_GET(T) \
+template<> \
+inline T RPCStream::get( void ) \
+{ \
+    return get_##T(); \
+}; \
+
+TEMPL_GET(bool)
+TEMPL_GET(int8_t)
+TEMPL_GET(uint8_t)
+TEMPL_GET(int16_t)
+TEMPL_GET(uint16_t)
+TEMPL_GET(int32_t)
+TEMPL_GET(uint32_t)
+TEMPL_GET(int64_t)
+TEMPL_GET(uint64_t)
+TEMPL_GET(double)
+TEMPL_GET(float)
+TEMPL_GET(string)
+TEMPL_GET(uid)
+
+template<class T>
+inline T RPCStream::get( void )
+{
+    return ::sorry_this_return_type_is_not_defined();
+}
+
+}
+}
+#endif
+
+/**
+ * $Log$
+ * Revision 1.8  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.7  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.6  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.5  2005/04/21 19:41:57  plasmahh
+ * after work sync
+ *
+ * Revision 1.4  2005/01/21 23:34:31  plasmahh
+ * more ideas and stuff
+ *
+ * Revision 1.3  2004/11/30 23:00:52  plasmahh
+ * more docs etc. etc.
+ *
+ * Revision 1.2  2004/11/30 12:53:30  plasmahh
+ * more stuff to go...
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/protocol.h
===================================================================
--- /tags/help/iwearrpc/include/protocol.h (revision 2256)
+++ /tags/help/iwearrpc/include/protocol.h (revision 2256)
@@ -0,0 +1,149 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_PROTOCOL_H
+#define __IWREMOTE_PROTOCOL_H
+
+#ifndef __IWEAR_BUILDPHASE
+#include <iwear/buildphase.h>
+#endif
+
+#define RPC_PORT	4242
+
+// Packet types (max. 255)
+#define MSG_CODE_SSLSTARTUP	0x00 ///< This requests a ssl connection
+#define MSG_CODE_ASSOCIATE	0x01
+#define MSG_CODE_DEASSOCIATE	0x02
+#define MSG_CODE_CALL_OBJECT	0x03
+#define MSG_CODE_CALL_RETURN	0x04	
+#define MSG_CODE_CALL_ERROR	0x05	
+#define MSG_CODE_CALL_REJECT	0x06
+#define MSG_CODE_ERROR		0x07
+#define MSG_CODE_RETURN		0x08
+#define MSG_CODE_ASS_RETURN	0x09
+#define MSG_CODE_ASS_REJECT	0x0A
+#define MSG_CODE_SEARCH		0x20
+#define MSG_CODE_SEARCHRETURN	0x21
+#define MSG_CODE_SSLDATA	0x30
+#define MSG_CODE_PROXY		0x40
+#define MSG_CODE_SUBPROTO	0xFF	///< Reserved
+
+
+#define MSG_SEARCH_CID		0x00000001
+#define MSG_SEARCH_UID		0x00000002
+#define MSG_SEARCH_CUID		0x00000003
+
+//Packet flags
+#define MSG_FLAG_SSL		0x01		///< If the packet contains SSL encrypted data
+#define MSG_FLAG_GZIP		0x02		///< If the packet is gzip compressed
+#define MSG_FLAG_SEQ		0x04		///< If the packet is sequencced (i.e. field 4)
+#define MSG_FLAG_RES1		0x08		///< Reserved for future use
+#define MSG_FLAG_RES2		0x10		///< Reserved for future use
+#define MSG_FLAG_RES3		0x20		///< Reserved for future use
+#define MSG_FLAG_RES4		0x40		///< Reserved for future use
+#define MSG_FLAG_RES5		0x80		///< Reserved for future use
+
+#define MSG_REASON_UNDEFINED	0x00000000
+#define MSG_REASON_NOCID	0x00000001 // no such class id
+#define MSG_REASON_NOUID	0x00000002 // no such uid
+#define MSG_REASON_NOCUID	0x00000003 // no such uid+classid
+#define MSG_REASON_NOCHAN	0x00000004 // Invalid channel
+#define MSG_REASON_SECURITY	0x00000005
+#define MSG_REASON_DEFECT	0x00000006 // The package had some defect
+#define MSG_REASON_INTERNAL	0x00000007 // An internal error was detected
+#define MSG_REASON_UNSUPPORTED	0x00000008 // Something is unsupported
+#define MSG_REASON_BUFFER	0x00000009 // Not enough buffer space for operation
+
+namespace iwear {
+class uid; // we need to keep this forward declaration otherwise the
+// RemoteConnection would explod into our face right away.
+    namespace net {    
+// these typedefs are for iwear-rpc specific important typedefs
+
+/**
+ * A cid_t is the "Class ID" type, which is for specifying a unique identifier
+ * for the class-interface that is implemented.
+ */	
+typedef uint32_t cid_t;
+
+typedef uint16_t chanid_t;
+/**
+ * Although the ID for Object and Host are both uids, to distinguish the
+ * semantics of parameters, returns and variables we mean "this is a uid for an
+ * object"
+ */
+typedef iwear::uid oid_t;
+
+/**
+ * This means "I am a uid to specify a host"
+ */
+typedef iwear::uid hostid_t;
+}
+}
+
+#define SIZE_CID (sizeof(cid_t))
+///@todo FIXME These constants will probably be out of date in case we change the cid_t to 64Bit
+#define SIZE_WORD (4)
+#define SIZE_UID (16)
+#define SIZE_HEADER (SIZE_WORD+SIZE_WORD+SIZE_WORD)
+#define SIZE_SSLPREFIX (SIZE_WORD+SIZE_WORD)
+#define SIZE_CALLHEADER (SIZE_HEADER+SIZE_UID+SIZE_UID+SIZE_WORD)
+#define MAX_IWRPC_STRING 100000
+/*
+class 
+{
+private:
+protected:
+public:
+};
+*/
+
+#endif
+/**
+ * $Log$
+ * Revision 1.8  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.7  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.6  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.5  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.4  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.3  2005/04/25 21:36:39  plasmahh
+ * mag ich mag ich nicht
+ *
+ * Revision 1.2  2005/04/21 19:41:57  plasmahh
+ * after work sync
+ *
+ * Revision 1.1  2005/04/20 18:08:45  plasmahh
+ * har ahr
+ *
+ */
Index: /tags/help/iwearrpc/include/sslwrapper.h
===================================================================
--- /tags/help/iwearrpc/include/sslwrapper.h (revision 2253)
+++ /tags/help/iwearrpc/include/sslwrapper.h (revision 2253)
@@ -0,0 +1,54 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_SSLWRAPPER_H
+#define __IWREMOTE_SSLWRAPPER_H
+
+namespace iwear
+{
+    namespace net
+    {
+/**
+ * The purpose of this class is, that it is to be used as a RemoteConnection,
+ * but it should be SSL Encrypted. So it will use the documented SSL
+ * encapsulation mechanism to write SSL packets to the RemoteConnection it
+ * holds, and will present itself as a RemoteConnection
+ */
+class SSLWrapper: public RemoteConnection
+{
+private:
+protected:
+public:
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.1  2005/09/13 23:24:22  plasmahh
+ * hope Im in sync now
+ *
+ *
+ */
Index: /tags/help/iwearrpc/include/shmstream.h
===================================================================
--- /tags/help/iwearrpc/include/shmstream.h (revision 2215)
+++ /tags/help/iwearrpc/include/shmstream.h (revision 2215)
@@ -0,0 +1,103 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_SHMSTREAM_H
+#define __IWREMOTE_SHMSTREAM_H
+
+#include <iwremote/rpcstream.h>
+
+namespace iwear
+{
+    namespace net
+    {
+/**
+ * This class implements the interface for RPCStream objects as a SHM stream
+ * object, copying the data to a certain shm segment, where it then will be
+ * read from another local process.
+ */
+class SHMStream : public RPCStream
+{
+private:
+protected:
+    void* stream;
+public:
+    SHMStream( size_t );
+    virtual ~SHMStream();
+    /**
+     * Parses the next stream object and returns it as bool. Throws exception
+     * when failing.
+     *
+     * This will return a pointer and the size to the buffer. It will be valid
+     * only until another function has been called on this SHMStream (including
+     * destructor of course)
+     */
+    virtual std::pair<char *, uint32_t> get_buffer( void );
+
+    /**
+     * This sets the buffer content. The buffer then belongs to the stream and
+     * will be delete[]d as necessary (after copying to shm segment)
+     */
+    virtual void set_buffer( char*, uint32_t );
+
+    virtual bool get_bool( void );
+    virtual double get_double( void );
+    virtual float get_float( void );
+    virtual int get_int( void );
+    virtual long get_long( void );
+    virtual string get_string( void );
+    virtual uid get_uid( void );
+
+    virtual void put_bool( bool );
+    virtual void put_double( double );
+    virtual void put_float( float );
+    virtual void put_int( int );
+    virtual void put_long( long );
+    virtual void put_string( const string& );
+    virtual void put_uid( const uid& );
+
+    virtual size_t max_size( void );
+    virtual void resize( size_t );
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.4  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2005/01/21 23:34:31  plasmahh
+ * more ideas and stuff
+ *
+ * Revision 1.1  2004/12/02 22:39:04  plasmahh
+ * first code output generation possible (totally incomplete)
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/xdrstream.h
===================================================================
--- /tags/help/iwearrpc/include/xdrstream.h (revision 2229)
+++ /tags/help/iwearrpc/include/xdrstream.h (revision 2229)
@@ -0,0 +1,198 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_XDRSTREAM_H
+#define __IWREMOTE_XDRSTREAM_H
+
+#ifndef __IWREMOTE_RPCSTREAM_H
+#include <iwremote/rpcstream.h>
+#endif
+
+namespace iwear
+{
+    namespace net
+    {
+/**
+ * This class implements the interface for RPCStream objects.
+ * @todo TODO FIXME reimplement a clean buffer setting, receiving, creating and
+ * interchange with the xdr functions.
+ */
+class XDRStream : public RPCStream
+{
+private:
+protected:
+    /**
+     * This is the saved buffer when the buffer belongs to us
+     */
+    char * buf_;
+
+    /**
+     * This is the buffer we currently work on
+     */
+    char * buffer;
+
+    /**
+     * This is the size of the work-buffer (in octets)
+     */
+    size_t bufsize;
+
+    /**
+     * This is the current position in the buffer (in octets)
+     */
+    size_t bufpos;
+
+    /**
+     * This is the maximum position we have written so far, so reading beyond
+     * it should be avoided.
+     */
+    size_t maxbufpos;
+
+public:
+    /**
+     * Create the stream passing it a buffer. The buffer will only be used by
+     * the stream, not deleted if the stream ends its life.
+     */
+    XDRStream( char *, size_t );
+
+    /**
+     * Create the stream with its own internal buffer. The buffer belongs to
+     * the stream and is deleted if the stream ends.
+     */
+    XDRStream( size_t );
+
+    virtual ~XDRStream();
+
+    /**
+     * This returns the buffer and the amount of data that is already in the
+     * buffer. The real size of the buffer might be bigger, but the number says
+     * which bytes are already filled and ready for transmission.
+     * @see max_size
+     */
+    virtual std::pair<char *, uint32_t> get_buffer( void );
+
+    virtual std::pair<const char *, uint32_t> get_buffer( void ) const;
+    
+    virtual void set_buffer( char*, uint32_t );
+
+    virtual void replace_buffer( char*, uint32_t );
+
+    virtual void replace( RPCStream& );
+
+    /**
+     * Parses the next stream object and returns it as bool. Throws exception
+     * when failing.
+     */
+    virtual bool get_bool( void );
+    virtual double get_double( void );
+    virtual float get_float( void );
+    virtual string get_string( void );
+    virtual uid get_uid( void );
+
+    virtual void put_bool( bool );
+    virtual void put_double( double );
+    virtual void put_float( float );
+    virtual void put_string( const string& );
+    virtual void put_uid( const uid& );
+
+    virtual uint32_t data( void ) { return bufsize - bufpos; }
+
+
+    /**
+     * This returns the real size of the internal buffer in bytes, i.e. how
+     * many bytes can be filled into the stream.
+     */
+    virtual size_t max_size( void );
+
+    /**
+     * This asks for resizing the buffer. If the new size is bigger, the
+     * resulting buffer is either now bigger or this throws an exception.
+     * If the new size is smaller, the resulting buffer may be smaller, but
+     * must not be. An exception is not thrown in this case. This is for
+     * efficiency.
+     * @note If this stream uses an external set buffer, this buffer is not
+     * resized, but instead replaced by an internal buffer of the new size.
+     */
+    virtual void resize( size_t );
+
+    virtual int8_t get_int8_t( void );
+    virtual uint8_t get_uint8_t( void );
+
+    virtual int16_t get_int16_t( void );
+    virtual uint16_t get_uint16_t( void );
+
+    virtual int32_t get_int32_t( void );
+    virtual uint32_t get_uint32_t( void );
+
+    virtual int64_t get_int64_t( void );
+    virtual uint64_t get_uint64_t( void );
+
+    virtual void put_int8_t( int8_t );
+    virtual void put_uint8_t( uint8_t );
+
+    virtual void put_int16_t( int16_t );
+    virtual void put_uint16_t( uint16_t );
+
+    virtual void put_int32_t( int32_t );
+    virtual void put_uint32_t( uint32_t );
+
+    virtual void put_int64_t( int64_t );
+    virtual void put_uint64_t( uint64_t );
+
+    virtual void reset( void ) { bufpos = 0; }
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.9  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.8  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.7  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.6  2005/04/25 07:49:34  plasmahh
+ * gradegebogen, alle module müssen das gleiche haben
+ *
+ * Revision 1.5  2005/04/21 19:41:57  plasmahh
+ * after work sync
+ *
+ * Revision 1.4  2005/01/21 23:34:31  plasmahh
+ * more ideas and stuff
+ *
+ * Revision 1.3  2004/11/30 23:00:52  plasmahh
+ * more docs etc. etc.
+ *
+ * Revision 1.2  2004/11/30 12:53:30  plasmahh
+ * more stuff to go...
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
+
Index: /tags/help/iwearrpc/include/remotereference.h
===================================================================
--- /tags/help/iwearrpc/include/remotereference.h (revision 2215)
+++ /tags/help/iwearrpc/include/remotereference.h (revision 2215)
@@ -0,0 +1,250 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_REMOTEREFERENCE_H
+#define __IWREMOTE_REMOTEREFERENCE_H
+
+#ifndef __IWEAR_UTILITY_H
+#include <iwear/utility.h>
+#endif
+
+namespace iwear
+{
+
+/**
+ * This class is to hold references on remote objects. Every RemoteObject should be 
+ */
+template<class T>    
+class RemoteReference /*{{{*/
+{
+    friend class RemoteObject; ///< humm, I dont like friends... @todo find a better way
+public:
+   /**
+    * 
+    */
+    mutable T* ptr;
+
+   /**
+    * Constructs an emtpy Pointer, pointing to NULL
+    */
+    RemoteReference();
+
+   /**
+    * Constructs a Pointer pointing to _ptr. This also registers at _ptr for
+    * lifetime-end notification.
+    */
+    RemoteReference(T* _ptr);
+
+   /**
+    * This destroys the pointer object, and also deregisters it from
+    * notification of lifetime end 
+    */
+    virtual ~RemoteReference();
+
+    /**
+     * Dereference the pointer, just if it was a usual T*. This does not do any
+     * locking, since if needed, it would be done in the correct class. There
+     * could be little race condition with the object pointed to beeing
+     * currently destructed and then calling on an object not beeing there. But
+     * you can still cast to an ordinary pointer and do the same, so no need
+     * for this here...
+     * @note Although this operator can check for a few memory boundaries, it
+     * will not prevent you from accesing wrong memory and crashing your
+     * application.
+     */
+    T* operator->( void );
+
+    /**
+     * Just dereference the pointer to a reference of type T.
+     */
+    T& operator* ( void );
+
+    /**
+     * Assing one RemoteReference to another. The old ptr will be deregistered and the new
+     * one registered.  It might happen that during registering the object is
+     * currently beeing destructed, so the pointer assigned (and of course
+     * assigned from later on too) will be NULL.
+     */
+    RemoteReference& operator=( RemoteReference& v);
+
+    /**
+     * Does the same as the above, but as an assignment from ordinary pointer,
+     * e.g. one you got from new.
+     */
+    RemoteReference& operator=( T* _ptr);
+
+    /**
+     * Cast this pointer to a void* one. Usefull to display the virtual
+     * address.
+     */ 
+    operator T * (void);
+
+private:
+   /**
+    * Please do not call this function yourself, for the end user the
+    * assignment of NULL is the proper way. This is only to be called by the
+    * RemoteReferenceTracker class tracking this pointer.
+    */
+    virtual void reset( void ) const;
+};/*}}}*/
+
+template<class T>
+inline RemoteReference<T>::operator T * ( void )/*{{{*/
+{
+    return ptr;
+}/*}}}*/
+
+template<class T>
+inline void RemoteReference<T>::reset( void ) const /*{{{*/
+{ 
+//    cout << "Resetting Pointer from " << (void*) ptr << endl;
+    /// No need to deregister here since this is to be called from the Tracker class only    
+    ptr = NULL; 
+}/*}}}*/
+
+template<class T>
+inline RemoteReference<T>& RemoteReference<T>::operator=( RemoteReference<T>& v) /*{{{*/
+{ 
+    if ( ptr )
+    {
+	ptr->deregister_sptr(this);
+    }
+    ptr = v.ptr; 
+    if ( ptr )
+    {
+	try
+	{
+	    ptr->register_sptr(this);
+	}
+	catch(...)
+	{
+	    ptr = NULL;
+	}
+    }
+    return *this; 
+}/*}}}*/
+
+template<class T>
+inline RemoteReference<T>& RemoteReference<T>::operator=( T* _ptr) /*{{{*/
+{ 
+    if ( ptr )
+    {
+	ptr->deregister_sptr(this);
+    }
+
+    ptr = _ptr; 
+    if ( ptr )
+    {
+	try
+	{
+	    ptr->register_sptr(this);
+	}
+	catch(...)
+	{
+	    /// In case of error while registering we do not point to the
+	    /// object so we set us to 0 !!
+	    ptr = NULL;
+	}
+    }
+    return *this; 
+}/*}}}*/
+
+template<class T>
+RemoteReference<T>::~RemoteReference()/*{{{*/
+{
+    if ( ptr )
+    {
+	ptr->deregister_sptr(this);
+    }
+}/*}}}*/
+
+template<class T>
+RemoteReference<T>::RemoteReference() : ptr(NULL) /*{{{*/
+{ 
+    T::read_comment_on_this_function_please();
+
+    if (app_base_addr==NULL) 
+	get_app_base_addr(); 
+}/*}}}*/
+
+template<class T>
+RemoteReference<T>::RemoteReference(T* _ptr) : ptr(_ptr) /*{{{*/
+{ 
+    T::read_comment_on_this_function_please();
+
+    if (app_base_addr==NULL) 
+	get_app_base_addr(); 
+
+    ptr->register_sptr(this);
+}/*}}}*/
+
+template<class T>
+inline T& RemoteReference<T>::operator*( void )/*{{{*/
+{
+    return (*(operator->()));
+}/*}}}*/
+
+template<class T>
+inline T* RemoteReference<T>::operator->( void ) /*{{{*/
+{ 
+/*
+    cout << "Pointer points to " << (void*) ptr << endl;
+    cout << "Base Address is " << (void*) app_base_addr << endl;
+*/
+    if ( ptr )
+    {
+	
+	/// @todo Find a way to check the current segment boundaries in a fast way !!
+
+	if( ptr > app_base_addr )
+	{
+	    return ptr; 
+	}
+	else
+	{
+	    throw invptr_error(
+		string("Pointer to be dereferenced is pointing to invalid Memory (before main app) while attempting to dereference a ") 
+		+ demangle_cpp_name(typeid(T).name()) + " *");
+	}
+    }
+    else
+    {
+	throw nullptr_error(
+		string("NULL Pointer dereference while attempting to dereference a ") 
+		+ demangle_cpp_name(typeid(T).name()) + " *");
+    }
+}/*}}}*/
+
+}
+#endif
+
+/**
+ * $Log$
+ * Revision 1.2  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.1  2005/06/30 18:37:30  plasmahh
+ * sync
+ *
+ */
Index: /tags/help/iwearrpc/include/remotecaller.h
===================================================================
--- /tags/help/iwearrpc/include/remotecaller.h (revision 2215)
+++ /tags/help/iwearrpc/include/remotecaller.h (revision 2215)
@@ -0,0 +1,98 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_REMOTECALLER_H
+#define __IWREMOTE_REMOTECALLER_H
+
+namespace iwear
+{
+    namespace net
+    {
+/** 
+ * what reasons do we have why a call has come through ?
+ * @note the Trust whitelistings can be configured to a "trust all hosts/ssl
+ * keys which host/ssl key xyz does trust too. Here we do not distinguish
+ * between IPv4 and IPv6 adresses yet.
+ * @warning Always be aware that a host we trust due to 3rd party trust might
+ * be trusted by them due to 3rd party trust too.
+ * XXX sync with security providers knowledge
+ */
+enum pass_reason
+{
+    r_nolist,	///< Passed through because it wasnt in any black or whitelist
+    r_whitelist_ssl, ///< Passed through because SSL Key was whitelisted
+    r_whitelist_host4, ///< Passed through because IPv4 Host Adress was whitelisted
+    r_whitelist_host6, ///< Passed through because IPv6 Host Adress was whitelisted
+    r_whitelist_trust_ssl_host, ///< Passed through because we trust a certain
+    				///  SSL key which has told us to trust a certain host
+    r_whitelist_trust_host_ssl, ///< Passed through because we trust a certain host, which trusts a certain ss key
+    r_whitelist_trust_host_host,///< see the others
+    r_whitelist_trust_ssl_ssl, ///< see the others
+    num_pass_reason
+};
+/**
+ * This Class is a description of the Object that called us. It stores some
+ * information about it.
+ */
+class RemoteCaller
+{
+private:
+protected:
+public:
+    /**
+     * This is the RemoteConnection that is used to communicate with the
+     * object.
+     * It Contains connection info about the host, as well as the possible ssl
+     * key or the host adress if ipv4/6 connection.
+     * @note this is non-cons to allow it to be used for some stuff like
+     * getting rpcstreams
+     */
+    RemoteConnection* rmc;
+
+    /**
+     * The reason why this call has passed the delivery system and has reached
+     * the object now.
+     * @todo BIG FAT TODO we need to set this from within the security providers
+     */
+    pass_reason prsn;
+
+
+};
+
+}
+}
+
+#endif
+/**
+ * $Log$
+ * Revision 1.3  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.2  2005/04/18 20:13:58  plasmahh
+ * lm deregistration done now
+ *
+ * Revision 1.1  2004/12/02 22:41:13  plasmahh
+ * first code output generation possible (totally incomplete)
+ *
+ */
Index: /tags/help/iwearrpc/include/remoteobject.h
===================================================================
--- /tags/help/iwearrpc/include/remoteobject.h (revision 2256)
+++ /tags/help/iwearrpc/include/remoteobject.h (revision 2256)
@@ -0,0 +1,327 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_REMOTE_OBJECT_H
+#define __IWREMOTE_REMOTE_OBJECT_H
+
+#include <iwear/threadlocked.h>
+#include <stdint.h>
+#include <iwremote/protocol.h>
+#include <vector>
+#include <boost/intrusive_ptr.hpp>
+#include <iwear/utility.h>
+#include <iwremote/remoteconnection.h>
+
+namespace iwear
+{
+class uid;
+    namespace net
+    {
+
+enum rpc_side
+{
+    rpc_client,
+    rpc_server,
+    num_rpc_side,
+};
+
+class RemoteCaller;
+class CallManager;
+class RPCStream;
+class RemoteConnection;
+class CallProvider;
+
+class CallDescriptor /* {{{ */
+{
+private:
+protected:
+public:
+
+    /**
+     * The RemoteConenction is filled if this is a client object, the
+     * RemoteCaller is filled if its a server side object.
+     */
+    union 
+    {
+	/**
+	 * This is a descriptor for a connection to the server side object.
+	 */
+	RemoteConnection* rmcn;
+
+	/**
+	 * This is the RemoteCaller object of the Remote Host that called a
+	 * function. It will be set before a function, and then Reset right
+	 * after this function.
+	 */
+	RemoteCaller* rmcl;
+    } rmt;
+
+    /**
+     * The class that provided us with the caller or connection.
+     * We ask it for rpcstreams.
+     * There are two major cases what kind ob object we are
+     * - Client Object: In this case the callprovider has been set during the
+     *   association and can just be used to transfer the data to the server
+     * - Server Object: In this case, the CallProvider has been set together
+     *   with the RemoteCaller for the actual object.
+     *   
+     *   TODO What do we do in case of recursion ? Check if its the same RemoteCaller ?
+     * @note We should only need to worry about recursion in server side
+     * objects, since the clients are not callable (but instead might call
+     * other servers too). So maybe to allow local recursion we should not
+     * directly let the object be called, but instead wrap it the same way it
+     * would be on a server...
+     *
+     * XXX Another problem with recursion is, that we often cannot handle
+     * incoming data as long as this call is waiting for completion. A
+     * workaround could be the thread scheduling on the server side, but as it
+     * will be then client-side too, the other will arrive in another thread,
+     * which will be stuck in the mutex.
+     *
+     * Another idea is to check the caller, if its the same host/hostid and let
+     * it go through without the mutex. But it could then get stuck on the same
+     * internal mutexes on other objects structures. plus if the remote system
+     * fools us or is calloing from different threads our functions, it could
+     * come in that two functions are running without beeing locked.
+     * This could be a potential security risk.
+     *
+     * So the final decision as of 09/13 is to disallow recursion into objects
+     * alltogether and try to detect it and send an error message back.
+     */
+    CallProvider* cprov;
+
+    chanid_t channel;
+
+    rpc_side myside;
+}; /* }}} */
+
+class RemoteObject : virtual public ThreadLocked
+{
+private:
+protected:
+friend class RootArtano;
+friend class CallManager;
+friend class CallProvider;
+
+    virtual void set_uid( const uid& ) { }
+
+    CallDescriptor cd;
+
+    CallManager* cman;
+
+    uint32_t referrer;
+
+    CallManager* get_callmanager( void ) { return cman; }
+
+    CallProvider* get_callprovider( void ) { return cd.cprov; }
+
+    /**
+     * This is only validly filled if we are a client object. As a Server
+     * Object, we could server different remoteconnections, and thus different
+     * channels.
+     */
+    chanid_t channel_id;
+
+    float call_timeout;
+    /**
+     * Get the minimum size of a buffer needed for this kind of call
+     */
+    virtual size_t get_callminsize( uint32_t callid ) = 0;
+
+    virtual size_t get_retminsize( uint32_t callid ) = 0;
+
+    /**
+     * Get the minimum size needed for this object (If an object uses the
+     * additional dynamic object allocation functions, it needs to take those
+     * size into account)
+     */
+    virtual size_t get_minsize( void ) = 0;
+    
+    /**
+     * An dieser stelle haben wir das objekt bereits lokalisiert. Auf diesem
+     * Objekt wird nun der aufruf gestartet, indem der datenstrom geparsed
+     * wird. Vorher wurden RemoteCaller gesetzt und das objekt gelockt.
+     * (das sollten wir jetzt in do_call machen. das objekt selbst wird eine
+     * _resolve_call() methode implementieren...
+     *
+     * Jedes Objekt hat natürlich seine eigene art die daten zu parsen und die
+     * funktion festzustellen, daher hier pv.
+     *
+     * Die Position im strom is an der stelle wo die crcid liegt (danach kommt
+     * dann die version_id)
+     *
+     * TODO können wir das hier intern im objekt lösen, also das "externe"
+     * locken ? Wie ist das mit der rekursivität ? wenn wir ein andres objekt
+     * aufrufen das uns wiederum aufruft ?
+     * [Ja, non-virtual, wir wollen nicht dass uns jemand das überschreibt und
+     * was kaput macht]
+     */
+    RPCStream* do_call( const hostid_t hid, RPCStream* rpcs, RemoteConnectionPtr rcon,
+	    chanid_t chan, uint32_t func, uint32_t fver );
+
+    /**
+     * This function should be implemented by the actual object ( it is
+     * autogenerated there )
+     * It will lookup which function to call, and call it, returning the return
+     * stream (if any). This will include the versioning parameter.
+     */
+    virtual RPCStream* _resolve_call( uint32_t callid, uint32_t verid, RPCStream* ) = 0;
+
+
+    /**
+     * @todo TODO build a more sophisticated visibility and callability cheking.
+     */
+    bool is_visible();
+
+    /**
+     * This function will fill the stream with the object from client side (to
+     * be sent to the server). This means that "readonly" fields dont need to
+     * be (re-)transmitted.
+     */
+    virtual void fill_stream_client( RPCStream* rpcs ) = 0;
+    
+    /**
+     * This fills a stream from the Server side (to be sent to the client).
+     * This means that the server has to fill in all the data thats really
+     * needed to (re-)assemble the object properly.
+     */
+    virtual void fill_stream_server( RPCStream* rpcs ) = 0;
+
+    /**
+     * Fills the object from a clientstream (previously filled with
+     * fill_stream_client()) and writes only the values that are not set to
+     * readonly.
+     */
+    virtual void fill_from_clientstream( RPCStream* rpcs ) = 0;
+
+    /**
+     * On Client side, fill this object from a serverstream so that all fields
+     * are set.
+     */
+    virtual void fill_from_serverstream( RPCStream* rpcs ) = 0;
+ public:
+    RemoteObject( void );
+    virtual ~RemoteObject( void );
+    /**
+     * This is the uid the server/client recognized the object from.
+     */
+PH1  virtual const uid& get_uid( void ) const = 0;
+
+    virtual const string& get_name( void ) const = 0;
+
+    /**
+     * Every automatically generated object will have this implemented.
+     */
+    virtual RemoteObject* clone( void ) const = 0;
+
+    /**
+     * This will return all the class_ids we are supposed to implement.
+     */
+    virtual vector<cid_t> get_cid( void ) = 0;
+
+    /**
+     * returns true if this remote object somewhere implements the give cid
+     */
+    virtual bool implements( cid_t ) = 0;
+
+    /**
+     * This is highly experimental, as it should return a proper class
+     * implementing
+     */
+    static RemoteObject* instance( uint32_t cid );
+
+    /**
+     * Such a function should be implemented by each class, to pass it to the
+     * ClassProvider
+     */
+    static RemoteObject* instance( void );
+
+    /**
+     * This resolves a given callid number to a string, denoting a uniq string
+     * which might be needed in case the call is done via some webservices xml
+     * plugin etc.
+     */
+    virtual const string& call_to_string( cid_t callid ) = 0;
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.18  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.17  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.16  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.15  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.14  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ * Revision 1.13  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.12  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.11  2005/04/25 07:49:34  plasmahh
+ * gradegebogen, alle module müssen das gleiche haben
+ *
+ * Revision 1.10  2005/04/20 18:08:45  plasmahh
+ * har ahr
+ *
+ * Revision 1.9  2005/04/20 14:30:48  plasmahh
+ *  new files
+ *
+ * Revision 1.8  2005/04/20 13:43:13  plasmahh
+ * merged in fixes and addups for macosx
+ *
+ * Revision 1.7  2005/04/18 20:13:58  plasmahh
+ * lm deregistration done now
+ *
+ * Revision 1.6  2005/02/25 09:09:34  plasmahh
+ * kleinigkeiten
+ *
+ * Revision 1.5  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.4  2005/01/21 23:34:31  plasmahh
+ * more ideas and stuff
+ *
+ * Revision 1.3  2004/12/05 00:25:40  plasmahh
+ * iwremote stuff
+ *
+ * Revision 1.2  2004/12/02 22:39:04  plasmahh
+ * first code output generation possible (totally incomplete)
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/include/socketremoteconnection.h
===================================================================
--- /tags/help/iwearrpc/include/socketremoteconnection.h (revision 2256)
+++ /tags/help/iwearrpc/include/socketremoteconnection.h (revision 2256)
@@ -0,0 +1,154 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_SOCKETREMOTECONNECTION_H
+#define __IWREMOTE_SOCKETREMOTECONNECTION_H
+
+#include <iwremote/remoteconnection.h>
+#include <iwear/ipconnection.h>
+#include <iwremote/xdrstream.h>
+#include <boost/intrusive_ptr.hpp>
+
+namespace iwear
+{
+    namespace net
+    {
+
+/**
+ * This is a class that can wrap around different connection types to form a
+ * simple uniform interface to all possible interfaces.
+ */
+class SocketRemoteConnection : public RemoteConnection
+{
+friend class SocketProvider;
+private:
+protected:
+    IPConnection* scon;
+    /**
+     * The fd that was entered into the socket set (in case the connection has
+     * disabled itself)
+     */
+    int sockset_fd;
+
+    string ip;
+    char* buffer;
+    /**
+     * This is the timeout in seconds we use for sending and receiving data.
+     * If after this timeout no data has been transferred we consider this
+     * connection as dead (well, if we know that data should have been sent or
+     * arrived)
+     */
+    float io_timeout;
+
+    /**
+     * After this number of seconds we think that noone felt responsible for
+     * the packet that is in the queue and we throw away the packet or send a
+     * reject.
+     */
+    float buffer_timeout;
+    uint16_t port;
+
+    /// This information must be setable, and probably must be propagated to
+    /// the SocketProvider too, since the need of sequencing and the need of ssl
+    /// should be known there too. (this means only the non-packeted version of
+    /// ssl, the packeted version of ssl is done via SSLWrapper encapsulation)
+    bool is_udp;
+    bool need_ssl;
+    bool ssl_only;
+
+    SocketRemoteConnection( IPConnection*, CallProvider* cp, bool ms, float oto,float bto,float iot);
+
+    uint32_t& get_refcount( void ) { return refcount; }
+public:
+
+    void _debug_set_ip( const string& _ip ) { ip = _ip; }
+    void _debug_set_port( uint16_t p ) { port = p; }
+
+    static boost::intrusive_ptr<SocketRemoteConnection> 
+	create( IPConnection*, CallProvider* cp, bool ms, float oto,float bto,float iot);
+
+
+    virtual XDRStream* get_stream( uint32_t est );
+    virtual void recycle_stream( RPCStream* );
+
+
+    IPConnection& get_connection( void ) { return *scon; }
+    virtual ~SocketRemoteConnection();
+    virtual rpc_type get_type( void ) const { return rpc_remote; }
+
+    /**
+     * This function extracts the buffer from the given rpcstream and sends it
+     * over the connection. The stream must be suitable for the given
+     * connection type, the responsibility for this lies at the caller, we will
+     * here send everything over the connection.
+     */
+    virtual void send_rpcpacket( const RPCStream* spc );
+
+    /**
+     * This will try to receive a complete rpcstream packet, and set the buffer
+     * of the complete recived packet into the passed rpcstream
+     */
+    virtual bool receive_rpcpacket( RPCStream& spc, uint16_t channel );
+
+    virtual bool has_ipaddress( void ) const { return ip.length() != 0; }
+    virtual string get_ipaddress( void ) const { return ip; }
+
+    virtual bool has_sslkey( void ) const;
+    virtual bool get_sslkey( void ) const;
+
+    virtual bool is_connected( void ) const;
+    virtual bool reconnect( void );
+    virtual void disconnect( void );
+
+    virtual void set_connection_policy( void );
+
+friend void intrusive_ptr_add_ref( SocketRemoteConnection* rc );
+friend void intrusive_ptr_release( SocketRemoteConnection* rc );
+    
+};
+typedef boost::intrusive_ptr<SocketRemoteConnection> SocketRemoteConnectionPtr;
+
+inline void intrusive_ptr_release( SocketRemoteConnection* rc )
+{
+    ThreadLocker tl(rc->Mutex);
+    --(rc->get_refcount());
+    if( rc->get_refcount() == 0 )
+    {
+	delete rc;
+    }
+}
+
+inline void intrusive_ptr_add_ref( SocketRemoteConnection* rc )
+{
+    ThreadLocker tl(rc->Mutex);
+    ++(rc->get_refcount());
+    // Do we need to do more ?
+}
+
+}
+}
+
+#endif
+/**
+ */
Index: /tags/help/iwearrpc/include/chainsecurityprovider.h
===================================================================
--- /tags/help/iwearrpc/include/chainsecurityprovider.h (revision 2252)
+++ /tags/help/iwearrpc/include/chainsecurityprovider.h (revision 2252)
@@ -0,0 +1,81 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __IWREMOTE_CHAINSECURITPROVIDER_H
+#define __IWREMOTE_CHAINSECURITPROVIDER_H
+
+#include <iwremote/securityprovider.h>
+
+namespace iwear
+{
+    namespace net
+    {
+/**
+ * this provides a simple chain mechanism with options. The later directives
+ * override the former, a default policy can be set too. The directives are
+ * allow and deny with the uid( or a group of uids) or ip and optionally the
+ * requirement of ssl like:
+ *
+ * allow from 10.0.0.0/8
+ * deny from 10.1.0.0/16
+ * allow from 10.1.4.22 ssl
+ * allow from 10.1.4.23 to 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE ssl
+ * @note allow statements for object uids do *not* override generic connect
+ * statements.
+ * @warning a deny with ssl does allow non-ssl connections from this !
+ */
+class ChainSecurityProvider: public SecurityProvider
+{
+private:
+protected:
+public:
+    ChainSecurityProvider();
+    virtual ~ChainSecurityProvider();
+
+    virtual bool check_connection( RemoteConnectionPtr rcon );
+    /**
+     * if this returns true it means that we are ok with this hostid calling us
+     * in general (and with the connection too, like IP etc.)
+     */
+    virtual bool check_host( RemoteConnectionPtr rcon, const hostid_t& hid );
+
+    /**
+     * checks if this connection and hostid is allowed on this object uid
+     */
+    virtual bool check_object( RemoteConnectionPtr rcon, const hostid_t& hid, const oid_t& oid );
+};
+
+}
+}
+#endif
+/**
+ * $Log$
+ * Revision 1.2  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ *
+ */
Index: /tags/help/iwearrpc/Makefile.common
===================================================================
--- /tags/help/iwearrpc/Makefile.common (revision 2120)
+++ /tags/help/iwearrpc/Makefile.common (revision 2120)
@@ -0,0 +1,365 @@
+# This is a basic makefile that uses a flat directory structure. It could be
+# expanded to support multiple subdirectories and/or libraries
+#
+# Compilers to use
+CC=gcc
+CPP=g++
+AR=ar
+RANLIB=ranlib
+ECHOEN=echo -en
+OIDL2=/opt/gnome/bin/orbit-idl-2
+LEX=flex
+
+# Flags for the compilers
+#
+# Think about those as additionals :
+# -fvtable-gc
+# -ffunction-sections
+# -Wl,--gc-sections
+# -frepo
+# 
+CFLAGS= -pipe -Wall -g -O3 -ffast-math
+CPPFLAGS= -pipe -g -Wall
+#-O3 -march=pentium4 -mcpu=pentium4 -mfpmath=sse,387 -ffast-math -O3 
+#-march=pentium4 -mcpu=pentium4
+# -fstack-check -fmudflap
+#-fmudflapth -fmudflapir
+#-ansi -pedantic
+#-W
+#CPPFLAGS= -pipe -Wall -g -ffast-math -O3 -march=pentium4 -mcpu=pentium4
+#-mtune=pentium4
+
+
+
+# // How can we do this better ?
+ifneq ($(MAKECMDGOALS),steril)
+ifneq ($(MAKECMDGOALS),mrproper)
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(MAKECMDGOALS),distclean)
+ifneq ($(MAKECMDGOALS),dist)
+ifneq ($(MAKECMDGOALS),link)
+ifneq ($(MAKECMDGOALS),links)
+ifneq ($(NO_DEP_NEEDED),yes)
+
+# include dependencies files if it exists
+-include .depend
+endif
+endif
+endif
+endif
+endif
+endif
+endif
+endif
+
+# include generated configuration
+-include $(TOPDIR)/makefile.conf
+
+# Flags for the linker
+CPPLDFLAGS=$(LIBLIBS) $(LIBFLAGS)
+
+# Those need the stuff from makefile.conf
+BINDIR=$(PREFIX)/bin/
+SHAREDIR=$(PREFIX)/share/
+DOCDIR=$(SHAREDIR)/doc/packages/$(DISTDIR)
+LIBDIR=$(PREFIX)/lib/
+INCDIR=$(PREFIX)/include/
+LIB=$(LIBNAME).$(DYN_SUFFIX).$(LIBVERSION)
+STATLIB=$(LIBNAME).a
+
+# Where do we search for libfiles ?
+LIBINCLUDE=-L$(LIBDIR) -L$(LIBSEARCH)
+# Where do we search for include files ?
+INCLUDE=-I . -I $(PREFIX)/include/ $(INCLUDES) -I ./idl
+DEPFLAG=-MM $(INCLUDE) -I ./include
+
+# For displaying purposes
+#ESC=`echo -en "\033"`
+ESC=`$(ECHOEN) "\033"`
+RED="$(ESC)[1;31m"
+GRN="$(ESC)[1;32m"
+YEL="$(ESC)[1;33m"
+BLU="$(ESC)[1;34m"
+VIO="$(ESC)[1;35m"
+TUK="$(ESC)[1;36m"
+WHT="$(ESC)[1;37m"
+NOR="$(ESC)[m"
+
+STERILFILES?=nix
+STERILDIR?=nix
+EXTRACLEANFILES?=nix
+
+SUBDIR=$(notdir $(PWD))
+SUBLIBFILES=$(LIBFILES_$(SUBDIR))
+SUBLIBNAME=lib-$(SUBDIR).a
+SUBLIBFILES=$(foreach subdir,$(SRCDIRS), $(foreach file,$(LIBFILES_$(notdir $(subdir))),$(subdir)/$(file)))
+SUBLIBBASE=$(basename $(wildcard $(SUBLIBFILES)))
+
+SUBLIBFILES=$(foreach subdir,$(SRCDIRS), $(foreach file,$(LIBFILES_$(notdir $(subdir))),$(subdir)/$(file)))
+#SUBLIBCPPS=$(addsuffix .cpp, $(SUBLIBBASE))
+SRCFILES=$(foreach subdir,$(SRCDIRS), $(wildcard $(subdir)/*.cpp))
+SUBLIBS=$(foreach subdir,$(SRCDIRS),$(subdir)/lib-$(notdir $(subdir)).a)
+
+$(TOPDIR)/makefile.conf: 
+	@echo $(RED)You need to run $(TOPDIR)/configure before starting compilation$(NOR)
+	@exit 1
+
+ifeq ($(ROOTDIR),true)
+lib libs: $(TOPDIR)/lib/$(LIB) $(TOPDIR)/lib/$(STATLIB)
+
+$(TOPDIR)/lib/$(LIB): $(SUBLIBFILES)
+	@echo $(BLU)[LD]$(NOR) $(LIB)
+	@$(CPP) $(LIBINCLUDE) $(CPPLDFLAGS)$(LIB) $(SUBLIBFILES) -o $(TOPDIR)/lib/$(LIB)
+
+$(TOPDIR)/lib/$(STATLIB): $(SUBLIBFILES)
+	@echo $(BLU)[AR]$(NOR) $(STATLIB)
+	@$(AR) r $(TOPDIR)/lib/$(STATLIB) $(SUBLIBFILES)
+	@$(RANLIB) $(TOPDIR)/lib/$(STATLIB)
+
+trans:
+	@make -C $(TRANSDIR) trans
+merge:
+	@make -C $(TRANSDIR) merge
+
+extract:
+	@echo $(YEL)[XGETTEXT]$(NOR) $(SRCFILES)
+	@xgettext --omit-header -C -n -ktrans include/*.h $(SRCFILES) -j -o $(TRANSDIR)/$(TRANSTEMPLATE)
+endif
+
+$(LIBDIR):
+	@echo $(BLU)[MKDIR]$(NOR) $@
+	@mkdir -p $@
+
+$(INCDIR):
+	@echo $(BLU)[MKDIR]$(NOR) $@
+	@mkdir -p $@
+
+
+clean:
+	@echo $(VIO)[CLEAN]$(NOR) $(PWD)
+	@for dir in $(SRCDIRS); do \
+	    (rm -f *.o .depend* $$dir/*.moc.cpp $$dir/*.o $$dir/.depend* $$dir/$(EXTRACLEANFILES)) \
+	done
+
+distclean: steril
+	@echo $(VIO)[DISTCLEAN]$(NOR) $(PWD)
+	@rm -f *.tar.bz2 
+	@rm -f *.tar
+	@rm -f *.tar.rk
+
+mrproper steril: clean
+	@echo $(VIO)[STERIL]$(NOR) $(PWD)
+	@rm -rf $(STERILDIRS)
+	@rm -f $(STERILFILES)
+	@for dir in $(SRCDIRS); do \
+	    (rm -f *.a *.s $$dir/*.a $$dir/*.s *.log *.tag) \
+	done
+
+.PHONY: doku docs doc
+doku docs doc:
+	@rm -f doxygen.log
+	@echo $(BLU)[DOXYGEN]$(NOR) doxygen.conf \> doxygen.log 
+	@$(DOXYGEN) doxygen.conf &> doxygen.log
+
+# Generic targets for .o files
+%.o:%.cpp
+	@echo $(TUK)[CPP]$(NOR) $*.o
+	@$(CPP) $(CPPFLAGS) $(INCLUDE) -c $*.cpp -o $*.o
+
+%.o:%.cc
+	@echo $(TUK)[CPP]$(NOR) $*.o
+	@$(CPP) $(CPPFLAGS) $(INCLUDE) -c $*.cc -o $*.o
+
+%.s:%.cpp
+	@echo $(RED)[CPP -S]$(NOR) $*.s
+	@$(CPP) $(CPPFLAGS) -S $(INCLUDE) -c $*.cpp -o $*.s
+
+%.s:%.c
+	@echo $(RED)[CC -S]$(NOR) $*.s
+	@$(CC) $(CFLAGS) -S $(INCLUDE) -c $*.c -o $*.s
+
+%.o:%.c
+	@echo $(YEL)[CC]$(NOR) $*.o
+	@$(CC) $(CFLAGS) $(INCLUDE) -c $*.c  -o $*.o
+
+%.pp:%.cpp
+	@echo $(RED)[CC]$(NOR) $*.o
+	@$(CPP) $(CPPFLAGS) $(INCLUDE) -E -dD -c $*.cpp  -o $*.pp
+
+%.cc:%.lex
+	$(LEX) -f -o$*.cc $*.lex
+
+%.tab.h:%.y
+	$(YACC) -d $*.y
+
+.SECONDARY:$(wildcard */*.moc.cpp)
+
+define MOC_TEMPLATE
+$(1)/%.moc.cpp:include/%.h
+	@echo $$(TUK)[MOC]$$(NOR) $$^
+	@$$(MOC) $$^ > $$@
+endef
+
+$(foreach dir,$(SRCDIRS), $(eval $(call MOC_TEMPLATE,$(dir))))
+ifneq ($(ROOTDIR),true)
+
+sublib: $(SUBLIBFILES)
+	@echo $(BLU)[AR]$(NOR) $(SUBLIBNAME)
+	@$(AR) r $(SUBLIBNAME) $(SUBLIBFILES)
+	@$(AR) s $(SUBLIBNAME)
+
+dep depend .depend:
+	@echo $(TUK)[CPP -M]$(NOR) \*.cpp
+	@test `(ls -1 *.cpp 2>/dev/null | head -1)` && $(CPP) $(DEPFLAG) *.cpp > .depend 2> .depend.err || touch .depend
+	@echo $(YEL)[CC -M]$(NOR) \*.c
+	@test `(ls -1 *.c 2>/dev/null | head -1)` && $(CC) $(DEPFLAG) *.c >> .depend 2>> .depend.err || touch .depend
+	@echo -n $(RED)[CHECK]$(NOR) .depend.err" "
+	@(test -s .depend.err && echo [$(RED)ERROR$(NOR)]) || echo [$(GRN)OK$(NOR)]
+else
+depend dep .depend:
+	@echo $(VIO)[MAKE]$(NOR) $(SRCDIR)
+	@for dir in $(SRCDIRS); do \
+	    (cd $$dir; $(MAKE) depend) \
+	done
+	@rm -f .depend .depend.err
+	@for dir in $(SRCDIRS); do \
+	    (echo $(TUK)[CPP -M]$(NOR) $$dir/\*.cpp; \
+	    test `(ls -1 $$dir/*.cpp 2>/dev/null | head -1)` && $(CPP) $(DEPFLAG) $$dir/*.cpp 2>> .depend.err | sed -e "s|^[a-zA-Z0-9].*\.o|$$dir/&|" >> .depend || touch .depend; \
+	    echo $(YEL)[CC -M]$(NOR) $$dir/\*.c; \
+	    test `(ls -1 $$dir/*.c 2>/dev/null | head -1)` && $(CC) $(DEPFLAG) $$dir/*.c      2>> .depend.err | sed -e "s|^[a-zA-Z0-9].*\.o|$$dir/&|" >> .depend || touch .depend; \
+	    echo -n $(RED)[CHECK]$(NOR) .depend.err" "; \
+	    (test -s .depend.err && echo [$(RED)ERROR$(NOR)]) || echo [$(GRN)OK$(NOR)] ) \
+	done
+endif
+
+.PHONY: help lib libs $(DISTDIR)
+help:
+	@echo 
+	@echo $(WHT)Help for iwear $(DISTNAME)$(NOR)
+	@echo 
+	@echo Possible Targets \($(GRN)green$(NOR) is default target\)
+	@echo 
+	@echo -e $(GRN)lib$(NOR) "\t" Create ./lib/$(LIBNAME).so
+	@echo -e $(TUK)test$(NOR) "\t" Create test program\(s\) in $(SRCDIR)
+	@echo -e $(TUK)help$(NOR) "\t" Display this help screen
+	@echo -e $(TUK)depend$(NOR) "\t" Generate dependencies 
+	@echo -e $(TUK)clean$(NOR) "\t" Remove compiler generated files 
+	@echo -e $(TUK)steril$(NOR) "\t" Remove all generated files too
+	@echo -e $(RED)link$(NOR) "\t" Create links necessary for linking
+	@echo -e $(RED)dist$(NOR) "\t" Create links necessary for linking
+	@echo
+
+$(DISTDIR): distclean
+	@echo $(BLU)[MKDIR]$(NOR) $(DISTDIR)
+	@mkdir -p .$(DISTDIR)	
+	@cp -r * .$(DISTDIR)
+	@mv .$(DISTDIR) $(DISTDIR)-$(LIBVERSION)
+
+tar dist: $(DISTDIR)
+	@echo $(BLU)[TAR]$(NOR) $(DISTDIR)-$(LIBVERSION).tar.bz2
+	@tar cjf $(DISTDIR)-$(LIBVERSION).tar.bz2 $(DISTDIR)-$(LIBVERSION) 
+	@rm -rf $(DISTDIR)-$(LIBVERSION)
+	@mv $(DISTDIR)-$(LIBVERSION).tar.bz2 $$(pwd | sed 's/\/[^/]*$$//')
+	@echo "sed 's/%$(DISTNAME)_VERSION%/$(LIBVERSION)/" >> $$(pwd | sed 's/\/[^/]*$$//')/distseds
+
+rk rkdist: distclean
+	@echo $(BLU)[TAR]$(NOR) $(DISTDIR)-$(LIBVERSION).tar
+	@tar cf $(DISTDIR)-$(LIBVERSION).tar $(DISTDIR)-$(LIBVERSION) 
+	@echo $(BLU)[RK]$(NOR) $(DISTDIR)-$(LIBVERSION).tar.rk
+	@rk -mx $(DISTDIR)-$(LIBVERSION).tar.rk $(DISTDIR)-$(LIBVERSION).tar
+	@rm -f $(DISTDIR)-$(LIBVERSION).tar
+	@rm -rf $(DISTDIR)-$(LIBVERSION)
+
+iwear/iwear.h:
+	@echo $(YEL)Cannot find iwear/iwear.h did you forgot to $(RED)make link$(YEL) in iwear/$(SRCDIR) ?$(NOR)
+	@exit 1
+
+count cnt:
+	@echo $(GRN)[WC]$(NOR) *.cpp *.h
+	@find | egrep ".cpp$$|.h$$" | xargs wc
+
+scount scnt:
+	@echo $(GRN)[SLOCCOUNT]$(NOR) *.cpp *.h
+	@sloccount --addlangall .
+
+SRCHOME=$(PWD)
+
+#XXX Need to check if DISTNAME==* ??
+ifdef DISTNAME
+ifdef LIBNAME
+.PHONY: lnk links link rechts install
+rechts lnk links link: $(LIBDIR) $(INCDIR)
+	@echo $(GRN)[LN -s]$(NOR) $(LIB)
+	@cd $(LIBDIR); rm -f $(LIBNAME)*
+	@cd $(LIBDIR) ;ln -sf $(SRCHOME)/lib/$(LIB)
+	@cd $(LIBDIR) ;ln -sf $(LIB) $(LIBNAME).$(DYN_SUFFIX)
+	@echo $(GRN)[LN -s]$(NOR) $(LIBNAME).a
+	@cd $(LIBDIR) ;ln -sf $(SRCHOME)/lib/$(STATLIB) $(LIBNAME).a
+	@echo $(GRN)[LN -s]$(NOR) $(DISTNAME)
+	@cd $(INCDIR); rm -rf $(DISTNAME)
+	@cd $(INCDIR); ln -sf $(SRCHOME)/include/ $(DISTNAME)
+	@mkdir -p $(SHAREDIR)/locale/de_DE/LC_MESSAGES/
+	@mkdir -p $(SHAREDIR)/locale/ru_RU/LC_MESSAGES/
+	@mkdir -p $(SHAREDIR)/locale/zh_CN/LC_MESSAGES/
+	@mkdir -p $(SHAREDIR)/locale/fr_FR/LC_MESSAGES/
+	@cd $(SHAREDIR)/locale/de_DE/LC_MESSAGES/; ln -sf $(SRCHOME)/share/locale/de_DE/LC_MESSAGES/*.mo .
+	@cd $(SHAREDIR)/locale/ru_RU/LC_MESSAGES/; ln -sf $(SRCHOME)/share/locale/ru_RU/LC_MESSAGES/*.mo .
+	@cd $(SHAREDIR)/locale/zh_CN/LC_MESSAGES/; ln -sf $(SRCHOME)/share/locale/zh_CN/LC_MESSAGES/*.mo .
+	@cd $(SHAREDIR)/locale/fr_FR/LC_MESSAGES/; ln -sf $(SRCHOME)/share/locale/fr_FR/LC_MESSAGES/*.mo .
+
+
+install: lib
+	@echo $(YEL)Removing old files and versions$(NOR)
+	@cd $(DEST)$(LIBDIR); rm -f $(LIBNAME)*
+	@cd $(DEST)$(INCDIR); rm -rf $(DISTNAME)
+	@echo $(YEL)[CP]$(NOR) $(LIB)
+	@mkdir -p $(DEST)$(LIBDIR)
+	@cp $(TOPDIR)/lib/$(LIB) $(DEST)$(LIBDIR)
+	@echo $(YEL)[CP]$(NOR) $(STATLIB)
+	@cp $(TOPDIR)/lib/$(STATLIB) $(DEST)$(LIBDIR)
+	@echo $(GRN)[LN -s]$(NOR) $(LIBNAME).$(DYN_SUFFIX)
+	@cd $(DEST)$(LIBDIR); ln -s $(LIB) $(LIBNAME).$(DYN_SUFFIX)
+	@mkdir -p $(DEST)$(INCDIR)/$(DISTNAME)/
+	@cp include/*.h* $(DEST)$(INCDIR)/$(DISTNAME)/
+	@mkdir -p $(DEST)$(SHAREDIR)/locale/de_DE/LC_MESSAGES
+	@cd $(DEST)$(SHAREDIR)/locale/de_DE/LC_MESSAGES/; \
+	for mo in $(SRCHOME)/share/locale/de_DE/LC_MESSAGES/*.mo; do\
+	   (rm -f $$(basename $$mo); cp $$mo .) \
+	done
+	@mkdir -p $(DEST)$(SHAREDIR)/locale/ru_RU/LC_MESSAGES
+	@cd $(DEST)$(SHAREDIR)/locale/ru_RU/LC_MESSAGES/; \
+	for mo in $(SRCHOME)/share/locale/ru_RU/LC_MESSAGES/*.mo; do\
+	   (rm -f $$(basename $$mo); cp $$mo .) \
+	done
+	@mkdir -p $(DEST)$(SHAREDIR)/locale/zh_CN/LC_MESSAGES
+	@cd $(DEST)$(SHAREDIR)/locale/zh_CN/LC_MESSAGES/; \
+	for mo in $(SRCHOME)/share/locale/zh_CN/LC_MESSAGES/*.mo; do\
+	   (rm -f $$(basename $$mo); cp $$mo .) \
+	done
+	@mkdir -p $(DEST)$(SHAREDIR)/locale/fr_FR/LC_MESSAGES
+	@cd $(DEST)$(SHAREDIR)/locale/fr_FR/LC_MESSAGES/; \
+	for mo in $(SRCHOME)/share/locale/fr_FR/LC_MESSAGES/*.mo; do\
+	   (rm -f $$(basename $$mo); cp $$mo .) \
+	done
+
+doc-install:
+	@echo $(YEL)Removing old files and versions$(NOR)
+	@cd $(DEST)$(DOCDIR); cd ..; rm -rf $(DISTDIR)
+	@mkdir -p $(DEST)$(DOCDIR)
+	@echo $(YEL)[CP]$(NOR) doc
+	@cd doc;cp -r html $(DEST)$(DOCDIR)/
+	@cp COPYING $(DEST)$(DOCDIR)
+
+update:	
+	cvs update -dP
+	$(MAKE) steril
+	./configure
+	$(MAKE) -C . dep
+	$(MAKE) -C . lnk
+	$(MAKE) -C . lib
+	
+endif
+endif
+
+
+
Index: /tags/help/iwearrpc/TODO
===================================================================
--- /tags/help/iwearrpc/TODO (revision 2252)
+++ /tags/help/iwearrpc/TODO (revision 2252)
@@ -0,0 +1,42 @@
+
+
+build restriction for recursion
+mechanisms for recursion control (which thread does it, what do the waiting ones, locks etc.)
+
+Hm, wenn wir verschiedene classids in der implementationshierarchie
+unterstützen, wäre es vielleicht nötig hier 64Bit werte zu nehmen ?
+
+
+Fragen in ##C++ nach:
+wird bei einer map auch der key neu gesetzt ? wenn nicht, dann alle map<uid*
+überprüfen weil dann kanns passieren dass die uids wech sind...
+
+
+Können wir das ganze vielleicht als bootstrap prozess benutzen um einige
+interne funktionen über autogenerierte dinge abzubacken so dass wir etliche
+nachrichten vielleicht nicht von hand zusammensetzen müssen... ?
+
+mehr typedefs einsetzen, z.b. für die uids als host_id object_id etc.
+
+
+
+hm, vielleicht sollten wir noch solche sachen wie "security requested" etc. in
+unsere sachen mit aufnehmen ? (hm, meine ich damit beim aufruf oder assoziation
+oder resolve oder sowas ? vermutlich...)
+
+Als locator für hosts könnte man vielleicht das edonkey netz missbrauchen...
+
+add to configure:
+check for CHAR_BIT == 8
+check for int ->uint -> int conversion works
+
+noch ein "piggyback" flag welches sagt dass da noch spezielle andre daten
+sind... aber wie sind die zu unterscheiden ?
+
+connection lost/abgebrochen etc. -> assoziationen lösen
+
+cache persistence hinbasteln, autogenerated code in testclient.cpp
+
+persistent connection timout nachdem die verbindung abgebrochen wird
+
+thread safety: dont leep locks while waiting for connections
Index: /tags/help/iwearrpc/doc/idlformat.tex
===================================================================
--- /tags/help/iwearrpc/doc/idlformat.tex (revision 1410)
+++ /tags/help/iwearrpc/doc/idlformat.tex (revision 1410)
@@ -0,0 +1,201 @@
+
+Ein idl file ist eine beschreibung für das interface eines (oder mehrer)
+Objekte, welche Netzwerkfähig sind.
+Da ein solches Objekt einmal auf der Server Seite und einmal auf der Client
+Seite existiert, beschreibt das idl file die Sicht aus der serverperspektive.
+Das bedeutet z.B. für das keyword ''in'' bei einer Funktion dass der Server
+dieses objekt nur bekommt, und nicht wieder zurückschickt. Für nicht
+basisdatentypen bedeutet das, es wird eine const referenz übergeben. Für
+basisdatentypen der Wert. genaueres steht dann bei den jeweiligen keywords.
+
+
+Keywords
+
+-- namespace --
+Leitet einen Namensraum ein, welcher durch die folgenden geschweiften Klammern
+({}) begrenzt wird. Analog zu C++ kann man diese in einer Hierarchie
+schachteln. Jedoch unterstützen wir keine anonymen namespaces.
+Anders als in C++ gibt es keinen Globalen namespace, d.h. definitionen müssen
+immer in einem eigens angelegten namespace sein. Ein namespace kann
+definitionen von Klassen und enums enthalten. Es gibt keine
+nicht-member funktionen oder globale variablen. Es werden zur Zeit
+auch keine unions unterstützt, ob dieses nötig ist, ist ohnehin
+fragwürdig.
+-- class --
+-- struct --
+Leitet eine Objektdefinition, ähnlich C++ ein. Diese kann aus
+Datenfeldern und memberfunktionen bestehen.
+-- function --
+function ist eigentlic kein keyword, aber da eine member funktion
+nicht durch ein solches eingeleitet wird möchte ich es hier einmal
+aufführen.
+
+Security Model
+
+Jedes Objekt (Serverseitig) hat gewisse Zugriffsrechte und ist daher
+von RemoteObject abgeleitet. Am besten ist es wohl wenn ich hier
+einmal den geplanten ablauf eines RPC Calls beschreibe.
+
+Ankommende Verbindung oder UDP Paket. Es wird zunächst geprüft ob der
+Host berechtigt ist eine Verbindung aufzubauen. Es gibt dafür zwei
+Modelle. Zum einen der wohl generell Modus von Sensor Systemen, welche
+immer für alle offen sind und anhand einer Blacklist verbotene Hosts
+überprüfen. Zum anderen (Ähnlich wie X-Windows) werden alle
+Verbindungen ausser den explizit erlaubten abgelehnt (Whitelisting).
+Nun nehmen wir an, dass unsere Verbindung durchkommt, es wird also
+angefangen zu Parsen. Aus der Caller-Host IP und der mitgeschickten
+uid wird ein Caller Objekt kreiert, welches mit dem Caller Socket
+assoziiert wird. Bleibt die Verbindung für mehrere Aufrufe offen, so
+wird nur noch die uid des aufrufers überprüft und ggf. mit einem
+anderen Caller objekt assoziiert, da wir durchaus verschiedene Caller
+über eine Verbindung zulassen wollen (proxying). Typischerweise bleibt
+jedoch die uid gleich, da sie den Caller Host repräsentiert.
+
+Nun wird diese Caller uid anhand von white und blacklisten erneut
+überprüft (hier immernoch auf einer generellen host/caller basis).
+Wird diese nun angenommen, so schaut das System nach ob das mit der
+angegebenen uid angesprochene objekt exisitiert. Existiert dieses,
+wird nun das Objekt gelockt, danach der objektinterne pointer für den
+Caller gesetzt und daraufhin eine generelle, polymorphe funktion
+aufgerufen welche das objektspezifische parsen des datenstroms
+übernimmt.
+
+Darin wird die aufzurufende funktion identifiziert und der datenstrom
+geparst. Kommt es hierbei zu einem Fehler so wird dieses an den
+aufrufenden Host weitergegeben. Nach dem erfolgreichen Parsen der
+Daten wird die eigentlich funktion aufgerufen. Diese kann nun
+ihrerseits über das Caller objekt detailliert überprüfen ob der aufruf
+von einem genehmigten Host kommt oder nicht. Damit nicht jeder für
+jedes Objekt und jede Funktion ACLs pflegen muss, wird ein genereller
+ACL Container bereitgestellt, sowie einige funktionen, über welche
+eine funktion dann bei bedarf einen check durchführen kann.
+
+Bei erfolgreicher rückkehr der funktion (es wurde keine exception
+geworfen) werden die Daten gesammelt, welche an den Aufrufer
+zurückgesandt werden müssen.
+
+Dieses Paremter senden nun ein wenig im detail.
+Jeder Parameter hat das Attribut in, out oder inout.
+Die betrachtung ist immer aus der Sicht des Servers.
+
+- in bedeutet für den Client, dass dieser diese Daten sendet, sie
+jedoch nicht verändert zurückbekommt. Der Server bekommt daher eine
+const reference übergeben und muss die Daten nicht nocheinmal in
+seinem Antwortpaket zurücksenden.
+- out bedeutet für den Client er übergibt lediglich eine Referenz
+(nicht const !) auf ein Objekt, welches dann entsprechend mit Daten
+gefüllt wird. Er muss nichts an den Server senden, dieser jedoch
+bekommt natürlich die Referenz auf ein solches Objekt übergeben und
+kann dieses mit Daten füllen. Er darf jedoch nicht von diesem Objekt
+lesen (es wird mit default werten gefüllt sein) wird dieses dann aber
+an den Client übertragen.
+- inout bedeutet im Grunde beides zusammen. Der Client übergibt eine
+(nicht const) referenz auf ein sendbares objekt. Dieses wird dann an
+den Server übertragen, welcher dann auf diesem Objekt arbeitet und es
+dann wieder zurückgibt. Das Objekt wird für die Zeit der bearbeitung
+auf dem Client gelockt, damit es nicht zu synchronisationsproblemen
+kommen kann.
+- oneway ist ein zusatz für funktionen welche void returnen.
+Normalerweise gibt eine Funktion etwas zurück, was dann auch von
+Server zum client übertragen wird. Selbst wenn es nur void ist, so ist
+die Information dass die Funktion zurückgekehrt ist. oneway nun sagt,
+dass die Funktion lediglich aufgerufen werden soll. Es kommen keine
+Daten zurück, nichteinmal exceptions. Sobald der Client das
+Funktionspaket erfolgreich an den Server gesendet hat kehrt diese
+funktion zurück. Dies kann Sinnvoll sein wenn nicht viel Zeit zum
+warten da ist, oder wenn es nicht so sehr wichtig ist dass die Daten
+wirklich angekommen und erfolgreich verarbeitet worden sind (z.B. wenn
+man eine exception sowieso ignorieren würde)
+
+Ein weiterer Zusatz für membervariablen ist readonly. Das bedeutet
+hier, dass ein solches Datum nur von der Client zur Server Seite
+übertragen wird, jedoch nicht zurück. Ein Server kann also zwar
+durchaus seine Lokale Kopie des Objektes ändern, jedoch wird diese
+Änderung nicht zurück zum Client übertragen.
+
+Ein Rückgabe wert, oder ein übergebener wert in rückgaberichtung kann
+auch als cached markiert sein. Das bedeutet das (konfigurierbar pro
+objekt? oder vielleicht besser global ? oder wie ?) eine rückgabe
+eines neue wertes maximal nach dieser zeit erfolgt. Sinnvoll ist das
+bei z.b. int get( void ); funktionen. Sofern die verbindung
+abgebrochen wurde, wird nochmals maximal diese zeit gewartet bevor
+eine exception geworfen wird. Währenddessen wird versucht die
+verbindung wiederherzustellen.
+
+Der funktionszusatz "deferrable" markiert eine funktion als
+aufschiebbar. Dies erzeugt zwei weitere funktionen, eine mit suffix
+_defer und eine mit suffix _cont (für continue). Die _defer variante
+erhält alle parameter wie sie die normale funktion auch hat, gibt
+jedoch void zurück. Sie returned sofort (nachdem intern die
+datenstrukturen für den call angelegt wurden). Die _cont variante
+returned den original rückgabe wert, es müssen jedoch nur die
+variablen übergeben die als out oder inout markiert sind. Je nach
+setting in dem objekt wird entweder eine exception geworfen wenn der
+call noch nicht vollendet wurde, oder er blockiert bis dahin. Das
+Problem mit der exception variante ist vielleicht das man
+normalerweise excptions nicht für den normalen programmfluss nutzen
+sollte. Daher ist eine immer blockierende variante vielleicht
+sinnvoller. Problematisch ist hier vielleicht auch das ein call von
+jemand anders (andrer thread) fortgesetzt werden könnte. Vielleicht
+sollte das return der _defer funktion ein objekt zurückliefern anhand
+dessen (und der callid) der aufruf korrekt zugeordnet werden kann.
+Dieses object muss dann als erster parameter der _cont funktion
+übergeben werden.
+
+ok, gehört vielleicht nicht grade in die idl sache aber einfach so als
+idee: 
+aufrufe können (als udp pakete z.b.) an mehrere hosts geschickt
+werden, die diese dann aufgrund ihrers wissens (mit hoplimit)
+versuchen an den eigentlichen zielhost weiterzugeben. Dies könnte
+paketverlust oder unterbrochene leitungen kompensieren. Durch call
+sequence IDs kann man dann die calls auseinanderhalten...
+
+Wenn eine Funktion als const markiert ist, so kann diese nur lokal
+aufgerufen werden und hat keine remote auswirkungen. Sie wird dann
+auch im C++ code als const markiert, darf also keine änderungen am
+objekt selbst vornehmen. (das mutable keyword existiert nicht, es kann
+synchronistationsproblem zwischen client und server verursachen)
+
+Das keyword "synced" bedeutet bei einer variablen das wennn auf diesem
+objekt eine funktion aufgerufen wird das objekt mit dem entfernten
+synchronisiert wird. Wie genau das geht müssen wir nochmal schaun.
+Aufjedenfall sollte wohl das eine das master das andre das slave dabei
+sein. ansonsten werden daten nur dann übertragen wenn sie als
+parameter einer funktion übergeben werden, oder einmal bei der
+assoziation.
+
+Wird eine klasse mit dynamic markiert, so muss diese eine virtuelle
+funktion dynamic_fill_from() und dynamic_fill_to() implementieren
+welche einen RPCStream übergeben bekommt. Dort kann dieses objekt dann
+dynamische daten die es hält etc. mit in den datenstrom schreiben.
+Diese muss es dann natürlich auch wieder aus dem datenstrom rausholen
+können. Dies ist dazu da um z.b. mit new gehaltene arrays etc. mit
+übertragen zu können, falls dieses benötigt wird. Dies geht zwar sehr
+in die nähe der implementation ist aber auch sehr flexibel. Es könnte
+auch einen "hack" ermöglichen über den ein programmierer von solchen
+objekten beliebige objektschachtelungen dynamischer objekte auf diese
+art in den datenstrom schreiben kann, indem es gewisse objekte sich
+selbst in den strom schreiben lässt.
+
+Hier ist dann jedoch noch anzumerken dass die allokierung des
+speichers für den strom dann noch geplant werden muss, da der strom
+normalerweise kein "auto-resize" unterstützt. vielleicht allokieren
+wir "stückchen" die wir dann nacheinander durch das netz schieben...
+
+Abschliessend ist zu sagen dass der IDL Compiler nur einfache checks
+durchführen wird, genaue typen und syntax checks werden dem C++
+compiler überlassen. Daher kann es schon einmal passieren dass zwar
+das idl file compiliert wird, jedoch nicht die generierten C++
+sourcen.
+
+Basisdatentypen mit denen das System umgehen kann sind :
+int, long int etc.
+float, double
+std::string
+KEIN char* !!! 
+
+der support für arrays wird später hinzugefügt
+
+Brauchen wir etwas für die QOS angaben ? was würde uns das nützen,
+inwiefern würden wir drauf reagieren können... andere transportmedien
+nutzen ? um proxying bitten ? mesh routing swarm approach !
Index: /tags/help/iwearrpc/doc/rpcformat.tex
===================================================================
--- /tags/help/iwearrpc/doc/rpcformat.tex (revision 1152)
+++ /tags/help/iwearrpc/doc/rpcformat.tex (revision 1152)
@@ -0,0 +1,435 @@
+\include{stylesheets/stylesheet.link}
+\usepackage{hyperref}
+
+\theauthor{Dennis Lubert}{}
+\theversion{$$Revision$$}
+\title{ XDR based RPC Protocol and Implementation}
+\begin{document}
+\createtitle
+\begin{abstract}
+Im folgenden wird ein RPC Protokoll beschrieben, was in seiner
+Codierung auf XDR basiert. Das Protokoll soll objektorientiertes
+Arbeiten ermöglichen, sowie mit verschiedenen Transportprotokollen wie
+z.B. IPv4 und IPv6 arbeiten können. Es soll Sicherheitsmerkmale wie
+SSL und Zugriffsbeschränkungen bei bedarf bereitstellen können und
+soll sowohl Speicherplatz- als auch Laufzeiteffizient sein.
+Insbesondere soll es ermöglichen Lokale Aufrufe über geeignete
+Mechanismen schneller zu gestalten. Zusätzlich sollen Mechanismen
+vorhanden sein um die besonderheiten in Mobilen Netzen auszunutzen
+bzw. zu kompensieren. Dies wären z.B. verlorene Datenpakete,
+unterbrochene Verbindungen aber auch multiple Routen.
+Weiterhin soll eine Infrastruktur beschrieben werden die das Suchen
+nach bestimmten Objekten oder Objekttypen zu ermöglichen.
+
+Desweiteren werden Features und Details einer Referenzimplementation
+gegeben. Das folgende ist noch sehr unsortiert, unvollständig und zu
+einem beträchtlichen Teil lediglich Notizen.
+\end{abstract}
+\section{Allgemeine Fähigkeitsbeschreibungen}
+Hier werden etwas detaillierter die Fähigkeiten beschrieben ohne
+jedoch zu sehr die Implementation offenzulegen.
+\subsection{Objekte und Aufrufe}
+\subsubsection{Objektzusammensetzung}
+Im Prinzip unterstützen wir ähnliche Arten der Objektzusammensetzung
+wie C++, jedoch in (teilweise stark) eingeschränkter Form. Dieses sind
+im einzelnen :
+\begin{itemize}
+\item Jedes Objekt kann aus anderen Objekten bestehen (Member Objects)
+\item Unterstützte Basisdatentypen sind 
+\texttt{float}, \texttt{double}, \texttt{int}, \texttt{long} und
+\texttt{long long} bzw. deren typedefs aus \texttt{<stdint.h>}
+\item Unterstützte Container aus der STL sind
+\texttt{std::list}, \texttt{std::vector}, \texttt{std::map} und 
+\texttt{std::string}
+\item Ausdrücklich \emph{nicht} unterstützt sind Pointer zu
+verschiedenen Datentypen \emph{insbesondere} \texttt{char*}
+\item enums werden als eigene Implementation unterstützt.
+\item Unions sind zur Zeit nicht vorgesehen. 
+\item C-Style Arrays fixer Grösse werden unterstützt und wie ein
+\texttt{std::vector} behandelt.
+\end{itemize}
+
+\subsubsection{Server Client Prinzip}
+Jede Art von Objekt gibt es in zwei Varianten. Server und Client. Die
+Server Variante ist diejenige die die reale Funktionalität
+bereitstellt. Die Client Variante ist ein Interface zu dieser
+Funktionalität. Obwohl beide Objekte mit dem gleichen Interface
+benutzt werden können gibt es jedoch wichtige Unterschiede.
+\paragraph{Server Objekt}
+Das Server Objekt stellt ein virtuelles Inteface dar, welches vom
+Programmmierer noch mit Funktionalität gefüllt werden muss (durch
+Ableitung). Ein Aufruf von einem entfernten Objekt wird mittels eine
+RPCStream Pakets an den Server ausgeliefert. Dieser wertet die Daten
+aus und ruft die virtuell abgeleitet Variante auf; somit die vom
+Programmierer bereitgestellte Funktionalität. Entsprechend der
+Rückgabe der Funktion wird wieder ein RPCStream Objekt
+zusammengestellt und zum Client zurückgesendet. Somit macht es für den
+Programmierer fast keinen Unterschied ob sein Objekt lokal oder remote
+genutzt wird. Natürlich gibt es auch einen Mechanismus um das Objekt
+eindeutig zu identifizieren (128Bit uid), und auch um die
+Funktinalität zu identifizieren. Diese Identifikation erfolgt aufgrund
+der Interfacebeschreibung. Zwei Objekte, von denen man eigentlich
+dachte sie wären vom gleichen Typ, sind daher inkompatibel sofern sich
+ihre Interfaces auch nur geringfügig voneinander unterscheiden.
+\paragraph{Client Objekt}
+Das Client Objekt benötigt keine weitere Implementation vom
+Programmierer und ist sofort Benutzbar, sofern ein geeignetes Server
+Objekt gefunden wurde. Das Client Objekt wird über die 128Bit uid mit
+dem entsprechenden Server Objekt assoziiert, was über den
+CallManager bzw. RPCManager passiert. Sofern möglich wird automatisch
+eine Verbindung hergestellt, um die sich der Nutzer des Objektes aber
+nicht kümmern braucht.
+\paragraph{Shortcut}
+Da ein Objekt meistens über seine uid oder seine mögliche
+Funktionalität gesucht wird, kann es durchaus passieren dass sich das
+gesuchte Objekt auf dem Lokalen Rechner befindet, es kann sogar
+passieren dass es sich im gleichen Prozess befindet. Hierzu wird nun
+ein Shorcut mechanismus vorgesehen, welcher die Kommunikation über ein
+(schnelleres) Shared Memory Segment vorsieht. Befindet sich das Objekt
+im lokalen Prozess so kann sogar dieses umgangen werden und die
+Funktion direkt aufgerufen werden.
+\subsubsection{Allgemeine Aufrufe und Parameter}
+Jeder Parameter einer Funktion hat eine der Eigenschaften \texttt{in},
+\texttt{out} und \texttt{inout}. Diese sind von der Server Seite (also
+der des Objektes mit der realen Funktionalität) aus zu sehen. Ein
+\texttt{in} bedeutet hier dass die Daten nur zu lesen sind, ein
+\texttt{out} bedeutet dass die Daten nur zum schreiben da sind, und
+ein \texttt{inout} folglich dass die Daten zum lesen und schreiben
+sind. Eine vorsichtige Wahl der Parameter kann hier die Netzlast
+deutlich verringern, wenn man drauf achtet dass nur die wirklich
+notwendigen Daten übertragen werden.
+\subsubsection{Connection Management}
+Im gegensatz zu z.B. Corba kann der Benutzer
+hier jedoch eine Verbindung mit einem virtuellen Interface
+bereitstellen über die sich der CallManager bzw. RPCManager Objekte
+und deren Verbindungen holen kann. Dies ist notwendig da insbesondere
+im mobilen Bereich es oftmals die Notwendigkeit gibt nicht-standard
+verbindungstypen zu benutzen, oder aber auch neue zu entwickeln welche
+zur Entwicklungszeit des \iwear RPC Systems noch nicht vorgesehen
+waren. So ist es einfach eigene Transportmechanismen vorzusehen, von
+denen dann das gesamte System Profitieren kann.
+\subsection{Spezielle Objekte und speziell Aufrufe}
+Um gewissen Randbedingungen bei der Kommunikation gerecht zu werden
+gibt es spezielle Arten von Objekten und Aufrufen auf diesen, bzw.
+spezielle Aufrufe auf ''normalen'' Objekten.
+\subsubsection{Synchrone Objekte}
+Objekte deren klassendeklaration das keyword \texttt{synchronous}
+behinhalten werden bei jedem Aufruf mit dem Remote Objekt
+synchronisiert. Dies birgt potentielle Konflikte, so dass bei diesem
+Objekttype ein Timestamp eingeführt wird, welcher die letzte
+Änderung und die letzte Synchronistation beinhaltet. Anhand derer wird
+versucht die Daten zu mergen (d.h. neuere überschreiben ältere). Dazu
+ist es natürlich nötig dass die Hosts annähernd gleich laufende Uhren
+haben. Dies muss, wenn diese Funktionalität gewünscht wird vom
+Benutzer gewährleistet werden. 
+Normale Objekte haben aber trotzdem die Funktion
+\texttt{synchronize()} welche aufgerufen werden kann um das Objekt
+manuell zu synchronisieren. Hierbei wird implizit davon ausgegangen,
+dass das Objekt auf der Serverseite das neuere ist.
+\subsubsection{Dynamische Objekte}
+Die Idee der Dynamischen Objekte ist, dass diese Pointer auf andere
+Objekte halten. Dieses können auch nicht Remote Objekte sein. Um
+dennoch ein handling von solchen Daten zu ermöglichen kann der
+efahrene Programmieres seine Objekte als dynamisch markieren. Somit
+wird nach dem schreiben des Objekts in den Datenstrom eine spezielle
+Funktion des Objektes aufgerufen, welche den Strom mit weiteren
+Benutzerdaten füllen kann. Natürlich muss dieser dann genauso aus dem
+Datenstrom entfernt werden können so dass die automatisch generierten
+Funktionalitäten nicht beeinträchtigt werden.
+\subsubsection{cached Funktionen}
+Wird eine Funktion als \texttt{cached} markiert, so werden die
+Rückgabewerte auf der Client Seite zwischengespeichert. Da dies
+natürlich nur funktionieren kann, wenn der Aufruf nicht von den
+Parametern abhängig ist, so kann nur eine Funktion als \texttt{cached}
+markiert sein, die Daten nur von der Server zur Client Seite
+überträgt. Wird eine solche Funktion innerhalb des Cache-Intervals
+(Standard 250ms) aufgerufen, so werden nur die gecachten Daten
+zurückgeliefert. Das Cache-Interval kann pro Objekt festgelegt werden.
+Bricht die Verbindung seit dem letzten erfolgreichen Remote Aufruf
+zusammen, so wird nocheinmal so lange wie das Cache-Interval
+gewartet\footnote{Dies kann möglicherweise konfigurierbar gemacht
+werden}. Währenddessen wird asynchron versucht die Verbindung
+wiederherzustellen.
+\subsubsection{oneway Funktionen}
+Es kann Fälle geben in denen man nicht daran interessiert ist, ob eine
+Funktion erfolgreich aufgerufen wurde oder nicht, man will lediglich
+einige Daten dort ''ablegen''. Ist dies bei einer Funktion der Fall, bei
+der nur vom Client zum Server Daten übertragen werden, so kann diese
+Funktion als \texttt{oneway} markiert werden. Diese Funktion kehrt
+sofort zurück, nachdem die internen Datenstrukturen zum Aufruf
+angelegt wurden. Der eigentlich Aufruf wird asynchron abgesetzt. Im
+Falle eines Fehlers wird keinerlei Rückmeldung gegeben.
+\subsubsection{deferrable Funktionen}
+Es gibt Funktionen die potentiell Länger dauern als man wirklich
+warten möchte, man kann statt zu warten etwas anderes tun. Solche
+Funktionen kann man als \texttt{deferrable} markieren. Dies erzeugt
+zwei weitere Funktionen, wovon die eine das Suffix \texttt{\_defer}
+trägt, die andere \texttt{\_cont} (für Continue). Die \texttt{\_defer}
+Variante funktioniert ähnlich der \texttt{oneway} Variante und kehrt
+sofort zurück, während versucht wird den Aufruf asynchron abzusetzen.
+Sie nimmt aber nur die Parameter, welche auch wirklich zum Server hin
+übertragen werden müssen. Die \texttt{\_cont} Variante nimmt nun die
+Parameter (und hat einen Rückgabewert) welche Informationen von der
+Server zur Client Seite übertragen. Bei einem Aufruf dieser Funktion
+wird der eigentliche aufruf Fortgesetzt. Hier kann natürlich ein
+Fehler auftreten, und eine \texttt{remote\_error} Exception geworfen
+werden.
+
+Um einen start mehrerer Deferrable Funktionen zu ermöglichen, gibt die
+\_defer Variante ein FunctionDefer Objekt zurück, welches die \_cont
+Variante erwartet um den Aufruf fortzusetzen. Dieses Objekt kann auch
+dazu bentutzt werden um den Status des Aufrufs festzustellen.
+\subsubsection{const Funktionen}
+Die Idee an einer const Funktion ist, diese lediglich Lokal
+auszuführen. Fraglich ist hier jedoch noch, woher genau die
+Implementation kommen soll. Ein Vorteil wäre es, wenn man const
+Funktionen aufrufen könnte, die zuvor geholte Werte des Objektes
+einfach nur nocheinmal auslesen würden. Dies könnte die Netzlast
+reduzieren, da nur an Synchronisationspunkten neue Daten über das
+Netzt geschickt werden müssten.
+\subsection{Sicherheit}
+Anders als einige andere Systeme werden wir versuchen Sicherheit
+bereits beim Design des Systems zu berücksichtigen. Jedes RemoteObject
+hat dazu mehrere Features und Zugriffsbeschränkungen. Dabei ist jedes
+Objekt per default nicht erreichbar.
+\subsubsection{Sichtbarkeit}
+Ein Objekt kann für alle Sichtbar sein, für bestimmte Hosts und für
+alle unsichtbar. Anstelle von Hosts kann man auch hier
+Authentifizierte Hosts angeben.
+\subsubsection{Authentifikation}
+Die primäre Art der Authentifikation soll über SSL und deren RSA
+Schlüssel sein. Es wäre auch möglich eine Passwortbasierte
+Authentifikation zu realisieren. Dazu müsste dann einmal pro Session
+ein Passwort angegeben werden, welches dann solange im Speicher
+bleibt. Die potentiellen Sicherheitsrisiken müssten hier noch
+überdacht werden.
+\subsubsection{Erreichbarkeit}
+Wenn ein Objekt Sichtbar ist, heisst es noch lange nicht dass man auch
+Aufrufe auf diesem Objekt machen kann. Genauso wie für die
+Sichtbarkeit gibt es auch für Aufrufe auf diesen Objekten richtlinien.
+Sowohl für schreibende als auch nur-lesende Aufrufe.
+\subsubsection{Detaillierte Informationen}
+Aus Effizienzgründen gelten diese Daten zunächst einmal für das
+gesamte Objekt. Für jeden Aufruf wird aber für dessen dauer eine
+Referenz auf eine Verbindungsinformation gesetztn, über den ein Objekt
+selbst mögliche Beschränkungen für diesen Aufruf implementieren kann.
+\subsection{Fehlerbehandlung auf Anwendungsebene}
+Wird bei einem Aufruf auf der Fehlerseite eine Exception aufgefangen,
+so wird diese mit ihrem Typ und Inhalt des Textfeldes übertragen und
+dort als remote\_error wiedergegeben. Dies ist zum einem um eine
+Kompatibilität herzustellen mit Systemen die keine Exceptions kennen,
+zum anderen kann auf der Server Seite eine Exception geworfen werden,
+die auf der Client Seite nicht existiert. Diese kann dann natürlich
+nicht dort wieder geworfen werden.
+\subsection{Fehlerbehandlung auf Protokollebene}
+Hier gehts um Fehler innerhalb der Datenübertragung. z.B. abgebrochene
+Verbindungen und zurückgewiesene aufrufe aber auch interface versions
+kollisionen.
+\section{IDL Dateiformat}
+Um Netzwerkfähige Objekte zu erstellen müssen diese eine grosse Menge
+an zusätzlicher Funktionalität bereitstellen. Da dieses jedoch immer
+nach dem gleichen Schema abläuft kann man dem Programmierer nicht nur
+Arbeit abnehmen, sondern auch mögliche Fehler vermeiden indem man
+diese Objekte aus IDL\footnote{Interface Description Language} Dateien
+generieren lässt. Bei der Entwicklung eines passenden Formates möchte
+ich mich möglichst nahe an der C++ Syntax halten, da das System
+zunächst dafür gedacht ist C++ Objekte zu erzeugen. Bei Erweiterungen
+und Features wird man einige Dinge wiederfinden welche auch in
+CorbaIDL, XMLRpcIDL und SunRPCIDL zu finden sind.
+\subsection{Syntax und Semantik}
+\subsection{Umsetzung}
+
+\section{XDR Protkolldetails}
+\subsection{Transportmedien}
+Als primäres Transportmedium ist IPv6 vorgesehen. Auch unterstütz wird
+natürlich IPv4. Direktei serielle Verbindungen zu Infrarot und
+Bluetooth Geräten sind auch vorgesehen.
+\subsubsection{TCP vs. UDP}
+Ähnlich SunRPC werden wir sowohl TCP als auch UDP unterstützen jedoch
+TCP als primäres Transport verwenden. UDP soll z.B. bei oneway
+Funktionsaufrufen zum einsatz kommen. Auch ist angedacht über das
+proxying Feature per UDP mehrere Pakete an den gleichen Host über
+verschiedene Proxy Systeme abzusetzen. Dies dann insbesondere für
+Suchen nach Objekten. So ist bei noch unbekannter Route (und nicht
+direkter Erreichbarkeit der Hosts) die Wahrscheinlichkeit höher dass
+ein Paket ankommt. Weitere Besonderheiten des Transportmediums und
+dessen Handling müssen noch erarbeitet werden, insbesondere in Bezug
+auf Mobile Systeme und deren Eigenschaften bei Netzverbindungen.
+\subsubsection{QoS}
+Auch die Qualität der Verbindung soll berücksichtigt werden. Zum einen
+beim migrieren auf andere mögliche Verbindungen, zum anderen beim
+zurückstellen oder auch verbieten von Aufrufen bei zu gesättigter
+Leitung.
+\subsubsection{Erweiterbarkeit}
+Da jedes dieser Transportmedien durch ein generelles Interface
+angesprochen wird, ist es recht einfach möglich neue
+Benutzerdefinierte Transportmedien für die Verbindung zu einem
+bestimmten Host anzugeben.
+\subsection{Datenpakete}
+Jede Nachricht wird mit einem 32Bit XDR Integer eingeleitet, welcher
+die gesamtlänge des Datenpaketes angibt, einschliesslich dieses
+Integer. Danach folgt ein weitere 32Bit wert, welcher ein vom
+aufrufenden festgelegten sequence wert beinhaltet, welcher auch bei
+antworten dadrauf zurückgeschickt werden muss, damit der Aufrufende
+Kanal bei möglicherweise mehreren gleichzeitigen aufrufen diese
+auseinanderhalten kann.
+\subsection{RPC Call on Object}
+Ein RPC Aufruf wird mit dem Code 0x00000003 eingeleitet, was bedeutet dass
+der Aufrufer auf dem entfernten System auf einem bestimmten Objekt
+eine bestimmte Funktion mit im Datenstrom stehenden Parametern
+aufrufen will.
+Danach kommt eine 128Bit uid welche den Aufrufenden Host beschreibt.
+Danach eine 128Bit uid welche das aufzurufende Objekt beschreibt.
+Danach ein 32Bit CRC Wert welcher die Funktion beschreibt.
+Dadrauf folgen als XDR Stream die Parameter für die Funktion. Das
+Datenformat wird in einem anderen Teil diese Dokumentes erklärt.
+\\
+\\
+\begin{tabular}{|l|l|l|}
+\hline
+\textbf{Offset} & \textbf{Bit length} & \textbf{Purpose/Value} \\
+\hline
+\texttt{0x00} & 32  & Length of the whole packet including this field \\
+\hline
+\texttt{0x00} & 32  & Sequence ID of the Call (set by caller host,host uniq)\\
+\hline
+\texttt{0x04} & 32  & \texttt{0x00000003} \\
+\hline
+\texttt{0x08} & 128 & Uid of the calling host system \\
+\hline
+\texttt{0x18} & 128 & Uid of the Object to be called \\
+\hline
+\texttt{0x28} & 32  & CRC-ID of the Function to be called \\
+\hline
+\vdots & \vdots & \vdots \\
+\hline
+\end{tabular}
+\\
+\subsection{RPC Return from Object}
+Natürlich geben viele funktionen auch etwas zurück, bzw. kommen zurück
+und das möchte man wissen. Nur oneway funktionen geben nichts zurück !
+\subsubsection{Reject}
+Wenn der Aufruf einer Funktion abgelehnt wird, so kommt ein Reject
+Paket zurück. Dieses wird durch 0x00000006 angezeigt. Daraufhin kommt
+ein 32 Bit Code welcher einen Grund angibt, wieso der Aufruf abgelehnt
+wurde. Danach kommen Reason Code spezifische Daten welche den Grund
+näher erläutern können. Reason Codes werden später definiert. Der Wert
+0x00000000 jedoch - das soll hier schonmal gesagt werden - bedutet
+eine Ablehnung ohne angabe von Gründen. Dies kann durchaus legitim
+sein, da man aus Sicherheitsgründen nicht mehr sagen möchte.
+
+Mögliche Gründe für eine Ablehnung können aber z.B. auch sein, dass
+die uid nicht gefunden wurde, ein Interface Versionskonflikt besteht
+oder das Objekt als nicht nutzbar markiert ist.
+\\
+	\\
+\begin{tabular}{|l|l|l|}
+\hline
+\textbf{Offset} & \textbf{Bit length} & \textbf{Purpose/Value} \\
+\hline
+\texttt{0x00} & 32  & Length of the whole packet including this field \\
+\hline
+\texttt{0x04} & 32  & \texttt{0x00000006} \\
+\hline
+\texttt{0x08} & 32 & Reason Code \\
+\hline
+\vdots & \vdots & \vdots \\
+\hline
+\end{tabular}
+\\
+\subsubsection{Error}
+Ein Fehlercode wird dann gesendet, wenn die Funktion zwar aufgerufen
+werden kann, jedoch ein Fehler aufgetreten ist. Dies ist
+typischerweise dann wenn eine Exception aufgetreten ist. Der Code
+hierfür ist 0x00000007 und wird direkt von einem Fehlercode gefolgt,
+welcher den genaueren Grund des Fehlers angibt (0x00000000 steht dabei
+für eine Exception). Danach folgen Fehlerspezifische Daten. Bei einer
+Exception sind das der exception Typ (als string, kann von System zu
+System abweichen) und ein Grund der Exception (\texttt{what()}
+funktion der exception). Es werden zur Zeit keine kompletten Exception
+Typen unterstützt, da es möglich ist das eine Aufgefangene Exception
+auf dem anderen System überhaupt nicht bekannt ist.
+\\
+	\\
+\begin{tabular}{|l|l|l|}
+\hline
+\textbf{Offset} & \textbf{Bit length} & \textbf{Purpose/Value} \\
+\hline
+\texttt{0x00} & 32  & Length of the whole packet including this field \\
+\hline
+\texttt{0x04} & 32  & \texttt{0x00000007} \\
+\hline
+\texttt{0x08} & 32 & Error Code \\
+\hline
+\vdots & \vdots & \vdots \\
+\hline
+\end{tabular}
+\\
+
+\subsubsection{Return}
+Ein Return Paket zu einer Funktion wird mit dem Code 0x00000004
+gekennzeichnet. Danach kommt die uid des Zielsystems (Aufrufer Host)
+und dann die uid des aufgerufenen Objektes. Dann die 32 Bit CRC-ID der
+Funktion welche aufgerufen wurde. Diese Daten mögen redundant
+erscheinen, jedoch kann eine Verbindung von mehreren Aufrufen genutzt
+werden, sogar ein Proxying oder Multiplexing wäre denkbar. Damit
+dieses nicht unnötig erschwert wird, werden die Daten hier
+mitgeliefert. 
+\\
+\\
+\begin{tabular}{|l|l|l|}
+\hline
+\textbf{Offset} & \textbf{Bit length} & \textbf{Purpose/Value} \\
+\hline
+\texttt{0x00} & 32  & Length of the whole packet including this field \\
+\hline
+\texttt{0x04} & 32  & \texttt{0x00000004} \\
+\hline
+\texttt{0x08} & 128 & Uid of the calling host system \\
+\hline
+\texttt{0x18} & 128 & Uid of the Object to be called \\
+\hline
+\texttt{0x28} & 32  & CRC-ID of the Function to be called \\
+\hline
+\vdots & \vdots & \vdots \\
+\hline
+\end{tabular}
+\\
+\subsection{CRC-ID}
+Was hat es mit dieser CRC-ID auf sich ? Es ist ein 32 Bit Wert,
+welcher eine Funktion einer Klasse eindeutig identifiziert. Zunächst
+wird eine CRC32 Prüfsumme über die komplette Klasse mit Namespace
+gemacht, d.h. inklusive Datenmember, Methoden und deren Parameter und
+qualifier. Dies ist die Klassen CRC-ID. Dazu kommt dann die Funktion
+inklusive Parameter, das ist dann die Funktions CRC-ID. Anhand dieser
+wird dann die Funktion herausgesucht. So soll sichergestellt werden,
+dass bei einem Remote aufruf von der gleichen Interface Definition
+ausgegangen wird.
+\subsection{Version-ID}
+Es gibt auch eine Versions ID pro möglichen Aufruf. Diese wird beim
+Aufrufen mitgeschickt und fragt nach einem bestimmten Interface und
+dessen Version. Es bleibt, das wenn ein Interface sich irgendwie
+ändert sich die CRC-ID ändert und somit das ganze inkompatibel wird.
+Daher sollte man sich natürlich genaue Gedanken machen über das
+Interface das man spezifiziert.
+\subsection{Management Packets and Calls}
+Es gibt auch eine Menge Management Funktionalitäten. Dies sind zum
+einen die Frage nach bestimmten Objekten, deren Erreichbarkeit und
+auch die Suche nach bestimmten Interfaces, oder auch einfach eine
+Liste aller bekannten Objekte und deren Locations. Weiterhin gibt es
+auch Anfragen nach Proxying und auch reverse anfragen über indirekte
+Verbindungen oder Verbindungen über proxies. Auf gleiche Art und weise
+werden auch Broadcast Pakete verschickt, welche die Nachbarschaft über
+das Vorhandensein bestimmter Services informieren. Einige Server
+können daher transparent als eine Art directory Service fungieren und
+über eigene RPC calls weiter funktionalitäten bereitstellen.
+\section{Implementations Details}
+\subsection{XDR Protokoll}
+\subsection{SHM Protokoll}
+\subsection{CallManager}
+\subsection{C++ Code Generator}
+\subsection{Parser}
+Im Zuge des \iwear Projektes wurde der Parser für das IDL Format von
+Nikias Bassen geschrieben.
+\subsection{Generierter Code}
+\end{document}
Index: /tags/help/iwearrpc/src/translationunit.cpp
===================================================================
--- /tags/help/iwearrpc/src/translationunit.cpp (revision 1182)
+++ /tags/help/iwearrpc/src/translationunit.cpp (revision 1182)
@@ -0,0 +1,45 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <translationunit.h>
+namespace iwear
+{
+    namespace net
+    {
+void TranslationUnit::add_namespace( Namespace& st )
+{
+    namespaces.push_back(&st);
+}
+    }
+}
+
+/**
+ * $Log$
+ * Revision 1.2  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/src/socketprovider.cpp
===================================================================
--- /tags/help/iwearrpc/src/socketprovider.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/socketprovider.cpp (revision 2256)
@@ -0,0 +1,276 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <socketprovider.h>
+#include <iwear/debugstream.h>
+#include <iwear/scopetracer.h>
+#include <xdrstream.h>
+#include <socketremoteconnection.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+SocketProvider::SocketProvider( CallManager* cm )
+    : CallProvider(cm),
+      master_tcp4(IPv4, non_blocking),
+      master_tcp6(IPv6, non_blocking),
+      master_udp4(IPv4, non_blocking),
+      master_udp6(IPv6, non_blocking)
+{
+    ScopeTracer st(__FFL__);
+    try
+    {
+//    master_tcp4.bind(4242,IPv4);
+	master_tcp6.bind(4242,IPv6);
+	master_tcp6.listen();
+	master_udp6.bind(4242,IPv6);
+    } catch(const socket_error& se )
+    { 
+	d_err << "During creation of SocketProvider" << endl;
+	d_err << se << endl;
+	d_err << "Is any other service running ?" << endl;
+    }
+
+//    master_tcp4.listen();
+
+//    master_udp4.bind(4242,IPv4);
+}
+
+SocketProvider::~SocketProvider( )
+{
+    ScopeTracer st(__FFL__);
+    d_err << "Destroying a SocketProvider" << endl;
+}
+
+RPCStream& SocketProvider::get_callrpcstream( uint32_t callid, RemoteObject& )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+}
+
+RPCStream& SocketProvider::get_retrpcstream( uint32_t callid, RemoteObject& )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+}
+
+void SocketProvider::search_object( RPCStream& )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+}
+//TODO make this configurable. Max nr. of systemstreams in one providers queue
+#define MAX_QUEUE_WAIT 5
+pair<RPCStream*,RemoteConnectionPtr> SocketProvider::get_system_stream( double timeout )/*{{{*/
+{
+
+    ScopeTracer st(__FFL__);
+    if( msgq.size() < MAX_QUEUE_WAIT )
+    {
+	check_connections();
+    }
+
+    if( msgq.size() )
+    {
+	pair<RPCStream* ,RemoteConnectionPtr> r = msgq.front();
+	msgq.pop();
+	return r;
+    }
+    else
+    {
+	return make_pair(static_cast<RPCStream*>(0),static_cast<RemoteConnectionPtr>(0));
+    }
+}/*}}}*/
+
+void SocketProvider::check_connections( void )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+
+    check_for_incoming();
+    check_existing();
+}/*}}}*/
+
+void SocketProvider::check_existing( void )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+
+    ///@todo TODO find a way to check for disconnected connections (timeout)
+    vector<SocketConnection*>rs = socks.get_read( 0.01 );
+    vector<SocketConnection*>::iterator ri(rs.begin());
+/*
+    d_dbg << "This number of sockets is read to read: " << rs.size() << endl;
+    d_dbg << "From this number of checkable sockets:" << socks.size() << endl;
+*/
+    for(; ri != rs.end(); ++ri )
+    {
+	// get the SocketRemoteConnection from the private user data
+	void* ud = (*ri)->get_user_data();
+	if( ! ud ) THROW(iwlogic_error,("Got a SocketConnection without private data"));
+	RemoteConnection* rc = static_cast<RemoteConnection*>(ud);
+	SocketRemoteConnection* src = dynamic_cast<SocketRemoteConnection*>(rc);
+
+	if( ! src ) THROW(iwlogic_error,("Got a SocketConnection without proper SRC"));
+
+	d_dbg << "Connection " << ud << " is ready to read" << endl;
+
+	XDRStream* xdr = new XDRStream(0);
+	//TODO FIXME this does not really get the stream of the specified
+	//channel, this needs to be fixed and get into a clear way...
+
+	bool good = false;
+	try
+	{
+	    good = src->receive_rpcpacket( *xdr, 0 ); // only ask for a system stream packet
+	    // If we dont get a rpcpacket back, it might as well have other
+	    // packages saved in its internal per-chan-queue
+	}
+	catch( const exception& ce )
+	{
+	    d_dbg << "Could not receive rpcpacket an error occured." << endl;
+	    d_warn << ce << endl;
+
+	    socks.remove(**ri);
+	    (*ri)->disconnect();
+	}
+
+	d_dbg << "The System message queue size: " << msgq.size() << endl;
+	if( good )
+	{
+	    //mk here we should have a packet
+	    msgq.push(make_pair(xdr,src));
+	}
+	else
+	{
+	    d_dbg << "looks like we did not get a stream back..." << endl;
+	    delete xdr;
+	}
+    }
+}/*}}}*/
+
+void SocketProvider::check_for_incoming( void )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    TCPConnection* nc = dynamic_cast<TCPConnection*>(master_tcp6.accept(0.01));
+
+    if( nc )
+    {
+	d_dbg << "Got new Connection from " << nc->get_remote_ip() << " : " << nc->get_remote_port() << endl;
+	///@todo TODO check the connection policy for this host somehow
+
+	SocketRemoteConnectionPtr src = SocketRemoteConnection::create(nc,this,false,0.01,0.01,0.01);
+	///@todo TODO the timeout must come from somewhere else...
+	remote_connections.insert(src);
+	SocketConnection& sco = src->get_connection();
+	sco.set_user_data(dynamic_cast<RemoteConnection*>(src.get()));
+	socks.add(sco);
+	src->sockset_fd = sco.get_fd();
+    }
+}/*}}}*/
+
+void SocketProvider::_debug_print_state( void )/*{{{*/
+{
+    d_dbg << ANSI_BLUE << "System Msg Queue:" << ANSI_NORMAL << msgq.size() << endl;
+
+    d_dbg << ANSI_BLUE << "Remote Connections: " << ANSI_NORMAL << remote_connections.size() << endl;
+
+    set<RemoteConnectionPtr>::iterator rci( remote_connections.begin());
+    for(; rci != remote_connections.end(); ++rci )
+    {
+	d_dbg << ANSI_BLUE << "at " << (void*)rci->get() <<  ":" << ANSI_NORMAL;
+	if( (*rci)->is_connected() )
+	{
+	    d_dbg << "connected,";
+	}
+	else
+	{
+	    d_dbg << "disconnected,";
+	}
+	d_dbg << "IP=" << (*rci)->get_ipaddress() << endl;
+    }
+
+}/*}}}*/
+
+void SocketProvider::_debug_add_connection( RemoteConnectionPtr src )/*{{{*/
+{
+    SocketRemoteConnection* sx = dynamic_cast<SocketRemoteConnection*>(src.get());
+    remote_connections.insert(sx);
+    IPConnection& sc = (sx->get_connection());
+    sc.set_user_data(src.get());
+
+}/*}}}*/
+
+void SocketProvider::connected( RemoteConnectionPtr rc )
+{
+    try
+    {
+	SocketRemoteConnection* src = dynamic_cast<SocketRemoteConnection*>(rc.get());
+	if( src )
+	{
+	    socks.add(*(src->scon));
+	}
+    }
+    catch(...)
+    {
+	//XXX Do we really dont need to do anything ?
+    }
+}
+
+void SocketProvider::disconnected( RemoteConnectionPtr rc  )
+{
+    try
+    {
+	SocketRemoteConnection* src = dynamic_cast<SocketRemoteConnection*>(rc.get());
+	if( src )
+	{
+	    socks.remove(*(src->scon));
+	}
+    }
+    catch(...)
+    {
+	//XXX Do we really dont need to do anything ?
+    }
+}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.5  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.4  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.3  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.2  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ */
Index: /tags/help/iwearrpc/src/cppoutput.cpp
===================================================================
--- /tags/help/iwearrpc/src/cppoutput.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/cppoutput.cpp (revision 2256)
@@ -0,0 +1,1662 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <cppoutput.h>
+#include <namespace.h>
+#include <class.h>
+#include <function.h>
+#include <declaration.h>
+#include <enum.h>
+#include <fstream>
+#include <sstream>
+#include <map>
+
+#define ENDL "// by " << __FILE__ << "," << dec << __LINE__ << endl
+namespace iwear
+{
+    namespace net
+    {
+string header = "\
+ /* \n\
+  * This file is autogenerated by iwdl and should not be edited\n\
+  * instead edit the source .idl file this was generated from\n\
+  * if you find a bug in this code, please contact the authors\n\
+  * \n\
+  * $Id$\n\
+  */";
+
+CppOutput::CppOutput( const string& filebase_ )
+    : ccout(*(ccout_p = new ofstream((filebase_ + "client.cpp").c_str() ))),
+      chout(*(chout_p = new ofstream((filebase_ + "client.h").c_str() ))),
+      scout(*(scout_p = new ofstream((filebase_ + "server.cpp").c_str() ))),
+      shout(*(shout_p = new ofstream((filebase_ + "server.h").c_str() ))),
+      cmhout(*(cmhout_p = new ofstream((filebase_ + "common.h").c_str() ))),
+      cmcout(*(cmcout_p = new ofstream((filebase_ + "common.cpp").c_str() ))),
+      filebase(filebase_),
+      last_prot(private_t) // We have classes which are per default private...
+	  
+{
+}
+
+CppOutput::~CppOutput( ) 
+{
+    delete ccout_p;
+    delete chout_p;
+    delete scout_p;
+    delete shout_p;
+    delete cmhout_p;
+    delete cmcout_p;
+}
+
+void CppOutput::output_tu( TranslationUnit& tu )
+{
+    output_common(tu);
+    output_client(tu);
+    output_server(tu);
+}
+
+// {{{ Output Common Interface Class Files
+void CppOutput::output_common( TranslationUnit& tu )/*{{{*/
+{
+    cmhout << header << ENDL;
+    cmhout << ENDL;
+    cmhout << "#include <iwremote/callmanager.h>" << ENDL;
+    cmhout << "#include <iwremote/remoteobject.h>" << ENDL;
+    cmhout << "#include <iwremote/remotecaller.h>" << ENDL;
+    // TODO get rid of the usings to avoid namespace conflicts
+    cmhout << "using namespace iwear;" << ENDL;
+    cmhout << "using namespace iwear::net;" << ENDL;
+    cmhout << ENDL;
+
+    cmcout << header << ENDL;
+    cmcout << ENDL;
+    cmcout << "#include <" << filebase << "common.h>" << ENDL;
+    cmcout << "#include <iwremote/rpcstream.h>" << ENDL;
+    cmcout << ENDL;
+
+    list<Namespace*>& tus = tu.get_namespaces();
+    list<Namespace*>::iterator nit( tus.begin() );
+
+    for(; nit != tus.end(); ++nit )
+    {
+	output_common_namespace(**nit,0);
+    }
+}/*}}}*/
+
+void CppOutput::output_common_namespace( Namespace& ns, uint32_t indlev )/*{{{*/
+{
+    // First output the Header namespaces for common base classes
+    string ind = get_inds(indlev);
+
+    cmhout << ind << "namespace " << ns.id << ENDL;
+    cmhout << ind << "{" << ENDL;
+
+    cmcout << ind << "namespace " << ns.id << ENDL;
+    cmcout << ind << "{" << ENDL;
+
+    list<NamespaceItem*>::iterator nit( ns.items.begin() );
+
+    ++indlev;
+    for(; nit != ns.items.end(); ++nit )
+    {
+	switch( (*nit)->get_namespaceitem_type() )
+	{
+	    case namespace_t:
+		output_common_namespace(dynamic_cast<Namespace&>(**nit),indlev);
+		break;
+	    case class_t:
+		output_common_class(dynamic_cast<Class&>(**nit),0);
+		break;
+	    case enum_t:
+		output_common_enum(dynamic_cast<Enum&>(**nit),indlev);
+		break;
+	    default:
+		throw runtime_error("Invalid type for NamespaceItem");
+	}
+    }
+    cmhout << ind << "} // of namespace " << ns.id << ENDL;
+    cmcout << ind << "} // of namespace " << ns.id << ENDL;
+}/*}}}*/
+
+void CppOutput::output_common_enum( Enum& e, uint32_t indlev )/*{{{*/
+{
+    string inds = get_inds(indlev);
+    string inds2 = get_inds(indlev+1);
+
+    cmhout << inds << "enum " << e.id << ENDL;
+    cmhout << inds << "{" << ENDL;
+    list<EnumDef>& ed = e.get_enumdefs();
+    list<EnumDef>::iterator it = ed.begin();
+    for (; it != ed.end(); ++it )
+    {
+	cmhout << inds2 << it->id;
+	if ( it->value_set )
+	{
+	    cmhout << " = ";
+	    cmhout << it->value;
+	}
+	cmhout << "," << ENDL;
+    }
+    cmhout << inds2 << "num_" << e.id << ENDL;
+
+    cmhout << inds << "};" << ENDL;
+    cmhout << ENDL;
+}/*}}}*/
+
+void CppOutput::output_derivation( ostream& o, derivation d )/*{{{*/
+{
+	    switch ( d )
+	    {
+		case  public_d:
+		    o << "public ";
+		    break;
+		case  protected_d:
+		    o << "protected ";
+		    break;
+		case  private_d:
+		    o << "private ";
+		    break;
+                case  virtual_d:
+		    o << "virtual ";
+		    break;
+		case  public_virtual_d:
+		    o << "virtual public";
+		    break;
+		case  protected_virtual_d:
+		    o << "virtual protected";
+		    break;
+		case  private_virtual_d:
+		    o << "virtual private";
+		    break;
+		default:
+		    throw runtime_error("Invalid switch case");
+	    }
+}/*}}}*/
+
+void CppOutput::output_common_class( Class& c, uint32_t indlev )/*{{{*/
+{
+    c.generate_crcids("");
+    last_prot = private_t;
+    // First, output client header definition...
+    string inds = get_inds(indlev);
+    string inds1 = get_inds(indlev+1);
+
+    // output class <ourclassname>_Client : public <ourclassname>
+    cmhout << inds << "class " << c.id;
+
+    cmhout << " : ";
+    if ( c.subclasses.size() )
+    {
+	list<SubClass>::iterator it = c.subclasses.begin();
+	for ( ; it != c.subclasses.end(); ++it)
+	{
+	    output_derivation(cmhout,it->d_t);
+	    if ( it->d_t != public_virtual_d &&
+		    it->d_t != protected_virtual_d &&
+		    it->d_t != private_virtual_d )
+	    {
+		cmhout << "virtual ";
+	    }
+
+	    /*
+	    if ( it != c.subclasses.begin() )
+	    {
+		cmhout << ", ";
+	    }
+	    */
+	    cmhout << it->d_class->id;
+	    cmhout << " ,";
+	}
+    }
+    cmhout << ENDL;
+    cmhout << inds1 << "public virtual iwear::net::RemoteObject" << ENDL;
+
+    cmhout << inds << "{" << ENDL;
+    // Here goes the class definition... all the data members are already here,
+    // just output functions
+
+    list<ClassItem*>::iterator cit( c.items.begin() );
+    ++indlev;
+    for(; cit != c.items.end(); ++cit)
+    {
+	switch( (*cit)->get_classitem_type() )
+	{
+	    case function_cit:
+		output_common_function(dynamic_cast<Function&>(**cit),indlev);
+		break;
+	    case declaration_cit:
+		output_common_declaration(dynamic_cast<Declaration&>(**cit),indlev);
+		break;
+	    case class_cit:
+		output_common_class(dynamic_cast<Class&>(**cit),indlev);
+		break;
+	    case enum_cit:
+		output_common_enum(dynamic_cast<Enum&>(**cit),indlev);
+		break;
+	    default:
+		throw runtime_error("ClassItem with wrong item type");
+	}
+    }
+
+    output_common_classcommon(c,indlev-1);
+
+    // And after all of them, output the end of the class ;)
+    cmhout << inds << "};" << ENDL << ENDL;
+}/*}}}*/
+
+void CppOutput::output_common_classcommon( Class& c, uint32_t indlev )/*{{{*/
+{
+    string indsh1 = get_inds(indlev + 1);
+    string indsh2 = get_inds(indlev + 2);
+    string indsh3 = get_inds(indlev + 3);
+
+    string inds1 = get_inds(1);
+    string inds2 = get_inds(2);
+    string inds3 = get_inds(3);
+
+    if ( protected_t != last_prot )
+    {
+	cmhout << "protected:" << ENDL;
+    }
+
+/* ===============================================================================================
+ * get_minsize (common to all base classes) {{{
+ */    
+    {
+	cmhout << indsh1 << "virtual size_t get_minsize( void );" << ENDL;
+
+	/*
+	 * The minsize is the minsize of this class plus the minsize of the subclasses.
+	 */
+	cmcout << "size_t " << c.id << "::get_minsize( void )" << ENDL;
+	cmcout << "{" << ENDL;
+	cmcout << inds1 << "size_t sz = " << c.data_size << ";" << ENDL;
+	cmcout << inds1 << "return sz;" << ENDL;
+	cmcout << "}" << ENDL;
+	cmcout << ENDL;
+    }
+/* }}}
+ * ===============================================================================================
+ */
+
+/* ===============================================================================================
+ * get_callminsize (common to all base classes) {{{
+ */    
+    {
+    cmhout << indsh1 << "virtual size_t get_callminsize( cid_t );" << ENDL;
+
+    /*
+     * Output the function to calculate the get_callminsize()
+     */
+    cmcout << "size_t " << c.id << "::get_callminsize(cid_t cid)" << ENDL;
+    cmcout << "{" << ENDL;
+    cmcout << inds1 << "size_t sz = 0;" << ENDL;
+    cmcout << inds1 << "switch( cid )" << ENDL;
+    cmcout << inds1 << "{" << ENDL;
+
+//    cout << "classitem list size: " << c.items.size() << ENDL;
+
+    map<uint32_t,ClassItem*> sclt;
+    list<ClassItem*>::iterator cit( c.items.begin() );
+    for(; cit != c.items.end(); ++cit)
+    {
+//	cout << "mapping " << c.id << "::" << (*cit)->id << " to " << (*cit)->crcid << ENDL;
+	sclt.insert(make_pair((*cit)->crcid,*cit));
+    }
+
+    map<uint32_t,ClassItem*>::iterator scit( sclt.begin() );
+
+    uint32_t oc = 0;
+    for(; scit != sclt.end(); ++scit)
+    {
+	switch( scit->second->get_classitem_type() )
+	{
+	    case function_cit:
+		{
+		    Function& f = dynamic_cast<Function&>(*scit->second);
+//		    cout << "Functions crcid : " << f.crcid << ENDL;
+		    if ( oc != f.crcid )
+		    {
+			cmcout << inds2 << "case 0x" << hex << f.crcid << "/*" << f.id << "*/:" << ENDL;
+			cmcout << inds3 << "sz = 0" << f.get_outsize() << ";" << ENDL;
+			cmcout << inds3 << "break;" << ENDL;
+			oc = f.crcid;
+		    }
+		}
+		break;
+	    case class_cit:
+	    case enum_cit:
+	    case declaration_cit:
+		break;
+	    default:
+		throw runtime_error("ClassItem with wrong item type");
+	}
+    }
+
+    cmcout << inds2 << "default:" << ENDL;
+    if ( c.subclasses.size() )
+    {
+	list<SubClass>::iterator it = c.subclasses.begin();
+	for ( ; it != c.subclasses.end(); ++it)
+	{
+	    cmcout << inds3 << "sz = " << it->d_class->id << "::get_callminsize(cid);" << ENDL;
+	}
+    }
+
+    cmcout << inds2 << "throw runtime_error(\"Invalid crc id in get_callminsize()\");" << ENDL;
+    cmcout << inds1 << "}" << ENDL;
+
+    cmcout << inds1 << "return sz;" << ENDL;
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+    }
+/* }}}
+ * ===============================================================================================
+ */
+
+/* ===============================================================================================
+ * get_retminsize (common to all base classes) {{{
+ */    
+    cmhout << indsh1 << "virtual size_t get_retminsize(unsigned int);" << ENDL;
+
+    /*
+     * Output the function to calculate the get_retminsize()
+     * the size returned is the minimum stream size needed to send a call from
+     * client to server containing all the data needed of the function
+     * arguments.
+     * We get the id for the call, so we switch case for it and there set the
+     * bytes number. If we were not able to find it, it might be in one of our
+     * subclasses. So we call the function then there.
+     */
+    cmcout << "size_t " << c.id << "::get_retminsize(unsigned int cid)" << ENDL;
+    cmcout << "{" << ENDL;
+    cmcout << inds1 << "size_t sz = 0;" << ENDL;
+    cmcout << inds1 << "switch( cid )" << ENDL;
+    cmcout << inds1 << "{" << ENDL;
+
+
+    map<uint32_t,ClassItem*> sclt;
+    list<ClassItem*>::iterator cit( c.items.begin() );
+    for(; cit != c.items.end(); ++cit)
+    {
+	sclt.insert(make_pair((*cit)->crcid,*cit));
+    }
+
+    map<uint32_t,ClassItem*>::iterator scit( sclt.begin() );
+
+    uint32_t oc = 0;
+    for(; scit != sclt.end(); ++scit)
+    {
+	switch( scit->second->get_classitem_type() )
+	{
+	    case function_cit:
+		{
+		    Function& f = dynamic_cast<Function&>(*scit->second);
+		    if ( oc != f.crcid )
+		    {
+			cmcout << inds2 << "case 0x" << hex << f.crcid << ":" << ENDL;
+			cmcout << inds3 << "sz = 9;" << ENDL;
+			cmcout << inds3 << "break;" << ENDL;
+			oc = f.crcid;
+		    }
+		}
+		break;
+	    case class_cit:
+	    case enum_cit:
+	    case declaration_cit:
+		break;
+	    default:
+		throw runtime_error("ClassItem with wrong item type");
+	}
+    }
+
+    cmcout << inds2 << "default:" << ENDL;
+    if ( c.subclasses.size() )
+    {
+	list<SubClass>::iterator it = c.subclasses.begin();
+	for ( ; it != c.subclasses.end(); ++it)
+	{
+	    cmcout << inds3 << "sz = " << it->d_class->id << "::get_retminsize(cid);" << ENDL;
+	}
+    }
+
+    cmcout << inds2 << "throw runtime_error(\"Invalid crc id in get_retminsize()\");" << ENDL;
+    cmcout << inds1 << "}" << ENDL;
+
+    cmcout << inds1 << "return sz;" << ENDL;
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+/* }}}
+ * ===============================================================================================
+ */
+    cmhout << inds1 << "virtual void fill_stream_client( RPCStream* rpcs );" << ENDL;
+    cmhout << inds1 << "virtual void fill_stream_server( RPCStream* rpcs );" << ENDL;
+    cmhout << inds1 << "virtual void fill_from_clientstream( RPCStream* rpcs );" << ENDL;
+    cmhout << inds1 << "virtual void fill_from_serverstream( RPCStream* rpcs );" << ENDL;
+    cmhout << inds1 << "virtual iwear::net::RemoteObject* clone( void ) const; " << ENDL;
+    cmhout << inds1 << "virtual std::vector<cid_t> get_cid( void ); " << ENDL;
+    cmhout << inds1 << "virtual bool implements( cid_t ); " << ENDL;
+    cmhout << inds1 << "virtual const std::string& call_to_string( cid_t ); " << ENDL;
+
+    cmcout << "iwear::net::RemoteObject* " << c.id << "::clone( void ) const" << ENDL;
+    cmcout << "{" << ENDL;
+    cmcout << "    UNIMPLEMENTED" << ENDL;
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+    
+/* ===============================================================================================
+ * get_cid() (common to all base classes) {{{
+ */
+    cmcout << "std::vector<cid_t> " << c.id << "::get_cid( void )" << ENDL;
+    cmcout << "{" << ENDL;
+    cmcout << "    std::vector<cid_t> ret;" << ENDL;
+    cmcout << "    ret.resize(1);" << ENDL;
+    cmcout << "    ret[0] = 0x" << hex << c.crcid << ";" << ENDL;
+
+    std::list<SubClass>::iterator sci(c.subclasses.begin());
+    for(; sci != c.subclasses.end(); ++sci )
+    {
+	cmcout << "{" << ENDL;
+	cmcout << "    const std::vector<cid_t>& ci = " << sci->d_class->id << "::get_cid();" << ENDL;
+	cmcout << "    ret.insert(ret.end(),ci.begin(), ci.end());" << ENDL;
+	cmcout << "}" << ENDL;
+    }
+
+    cmcout << "    return ret;" << ENDL;
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+    
+/* }}}
+ * ===============================================================================================
+ */
+
+/* ===============================================================================================
+ * get_cid() (common to all base classes) {{{
+ */
+    cmcout << "bool " << c.id << "::implements( cid_t cid )" << ENDL;
+    cmcout << "{" << ENDL;
+    cmcout << "    if( cid == 0x" << hex << c.crcid << " ) return true;" << ENDL;
+    cmcout << "    if( false ";
+    std::list<SubClass>::iterator soci(c.subclasses.begin());
+    for(; soci != c.subclasses.end(); ++soci )
+    {
+	cmcout << "|| " << soci->d_class->id << "::implements( cid ) " << ENDL;
+    }
+    cmcout << ") return true;" << ENDL;
+    cmcout << "    return false;" << ENDL;
+
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+
+/* }}}
+ * ===============================================================================================
+ */
+    cmcout << "const std::string& " << c.id << "::call_to_string( cid_t )" << ENDL;
+    cmcout << "{" << ENDL;
+    cmcout << "    UNIMPLEMENTED" << ENDL;
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+
+    cmcout << "void " << c.id << "::fill_from_clientstream( RPCStream* rpcs )" << ENDL;
+    cmcout << "{" << ENDL;
+    cmcout << "    UNIMPLEMENTED" << ENDL;
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+
+/* ===============================================================================================
+ * fill_stream_server (common to all base classes) {{{
+ */
+    {
+    cmcout << "void " << c.id << "::fill_from_serverstream( RPCStream* rpcs )" << ENDL;
+    cmcout << "{" << ENDL;
+
+    if ( c.subclasses.size() )
+    {
+	list<SubClass>::iterator it = c.subclasses.begin();
+	for ( ; it != c.subclasses.end(); ++it)
+	{
+	    cmcout << inds1 << it->d_class->id << "::fill_from_serverstream(rpcs);" << ENDL;
+	}
+    }
+
+    // We need to transmit only those fields that are not marked as readonly.
+    cit = c.items.begin();
+
+    for(; cit != c.items.end(); ++cit)
+    {
+	switch( (*cit)->get_classitem_type() )
+	{
+	    case declaration_cit:
+		{
+		    Declaration& d = dynamic_cast<Declaration&>(**cit);
+		    if ( !d.readonly )
+		    {
+			if ( d.type->builtin() )
+			{
+			    /// TODO FIXME TODO FIXME We need to figure out if
+			    /// its a base type and if not if convertible
+//			    cmcout << inds1 << "rpcs->put_" << d.type->id << "(" << d.id << ");" << ENDL;
+			    cmcout << inds1 << d.id << " = " << "rpcs->get_" << d.type->id << "();" << ENDL;
+			}
+			else
+			{
+			    cmcout << inds1 << d.id << ".fill_from_serverstream(rpcs);" << ENDL;
+			}
+		    }
+		}
+		break;
+	    case class_cit:
+	    case enum_cit:
+	    case function_cit:
+		break;
+	    default:
+		throw runtime_error("ClassItem with wrong item type");
+	}
+    }
+
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+    }
+
+/* }}}
+ * ===============================================================================================
+ */
+
+/* ===============================================================================================
+ * fill_stream_server (common to all base classes) {{{
+ */
+    {
+    cmcout << "void " << c.id << "::fill_stream_server( RPCStream* rpcs )" << ENDL;
+    cmcout << "{" << ENDL;
+    if ( c.subclasses.size() )
+    {
+	list<SubClass>::iterator it = c.subclasses.begin();
+	for ( ; it != c.subclasses.end(); ++it)
+	{
+	    cmcout << inds1 << it->d_class->id << "::fill_stream_server(rpcs);" << ENDL;
+	}
+    }
+
+    // We need to transmit only those fields that are not marked as readonly.
+    cit = c.items.begin();
+
+    for(; cit != c.items.end(); ++cit)
+    {
+	switch( (*cit)->get_classitem_type() )
+	{
+	    case declaration_cit:
+		{
+		    Declaration& d = dynamic_cast<Declaration&>(**cit);
+		    if ( !d.readonly )
+		    {
+			if ( d.type->builtin() )
+			{
+			    /// TODO FIXME TODO FIXME We need to figure out if
+			    /// its a base type and if not if convertible
+			    cmcout << inds1 << "rpcs->put_" << d.type->id << "(" << d.id << ");" << ENDL;
+			}
+			else
+			{
+			    cmcout << inds1 << d.id << ".fill_stream_server(rpcs);" << ENDL;
+			}
+		    }
+		}
+		break;
+	    case class_cit:
+	    case enum_cit:
+	    case function_cit:
+		break;
+	    default:
+		throw runtime_error("ClassItem with wrong item type");
+	}
+    }
+
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+    }
+/* }}}
+ * ===============================================================================================
+ */
+
+/* ===============================================================================================
+ * fill_stream_client (common to all base classes) {{{
+ */
+    {
+    cmcout << "void " << c.id << "::fill_stream_client( RPCStream* rpcs )" << ENDL;
+    cmcout << "{" << ENDL;
+    if ( c.subclasses.size() )
+    {
+	list<SubClass>::iterator it = c.subclasses.begin();
+	for ( ; it != c.subclasses.end(); ++it)
+	{
+	    cmcout << inds1 << it->d_class->id << "::fill_stream_client(rpcs);" << ENDL;
+	}
+    }
+
+    // We need to transmit only those fields that are not marked as readonly.
+    cit = c.items.begin();
+
+    for(; cit != c.items.end(); ++cit)
+    {
+	switch( (*cit)->get_classitem_type() )
+	{
+	    case declaration_cit:
+		{
+		    Declaration& d = dynamic_cast<Declaration&>(**cit);
+		    if ( !d.readonly )
+		    {
+			if ( d.type->builtin() )
+			{
+			    /// TODO FIXME TODO FIXME We need to figure out if
+			    /// its a base type and if not if convertible
+			    cmcout << inds1 << "rpcs->put_" << d.type->id << "(" << d.id << ");" << ENDL;
+			}
+			else
+			{
+			    cmcout << inds1 << d.id << ".fill_stream_client(rpcs);" << ENDL;
+			}
+		    }
+		}
+		break;
+	    case class_cit:
+	    case enum_cit:
+	    case function_cit:
+		break;
+	    default:
+		throw runtime_error("ClassItem with wrong item type");
+	}
+    }
+
+    cmcout << "}" << ENDL;
+    cmcout << ENDL;
+    }
+/* }}}
+ * ===============================================================================================
+ */
+
+//    shout << inds2 << "virtual void fill_stream_server( RPCStream* rpcs );" << ENDL;
+//    shout << inds2 << "virtual void fill_from_clientstream( RPCStream* rpcs );" << ENDL;
+//    shout << inds2 << "virtual void fill_from_serverstream( RPCStream* rpcs );" << ENDL;
+
+
+}/*}}}*/
+
+void CppOutput::output_common_function( /*Class& c,*/ Function& f, uint32_t indlev )/*{{{*/
+{
+    string indsu = get_inds(indlev-1);
+    string inds = get_inds(indlev);
+    if ( last_prot != f.prot )
+    {
+	last_prot = f.prot;
+	switch(last_prot)
+	{
+	    case private_t:
+		cmhout << indsu << "private:" << ENDL;
+		break;
+	    case protected_t:
+		cmhout << indsu << "protected:" << ENDL;
+		break;
+	    case public_t:
+		cmhout << indsu << "public:" << ENDL;
+		break;
+	    default:
+		throw runtime_error("Invalid switch case");
+	}
+    }
+
+    cmhout << inds << "virtual ";
+    output_function(cmhout,f,"");
+    cmhout << " = 0;" << ENDL;
+}/*}}}*/
+
+void CppOutput::output_common_declaration( Declaration& d, uint32_t indlev )/*{{{*/
+{
+    string inds = get_inds(indlev);
+
+    output_protection(cmhout,d.prot,indlev);
+    cmhout << inds;
+    /*
+    if ( d.readonly )
+    {
+	cmhout << "readonly ";
+    }*/
+    cmhout << d.type->id << " ";
+    cmhout << d.id << ";" << ENDL;
+}/*}}}*/
+
+// }}}
+// {{{ Output Server Interface Class Files
+void CppOutput::output_server( TranslationUnit& tu )/*{{{*/
+{
+    shout << header << ENDL;
+    shout << ENDL;
+    shout << "#include <" << filebase << "common.h>" << ENDL;
+    shout << "#include <iwremote/remoteobject.h>" << ENDL;
+    shout << "#include <iwremote/rpcstream.h>" << ENDL;
+    shout << ENDL;
+
+    scout << header << ENDL;
+    scout << ENDL;
+    scout << "#include <" << filebase << "server.h>" << ENDL;
+    scout << ENDL;
+
+    list<Namespace*>& tus = tu.get_namespaces();
+    list<Namespace*>::iterator nit( tus.begin() );
+
+    for(; nit != tus.end(); ++nit )
+    {
+	output_server_namespace(**nit,0);
+    }
+
+}/*}}}*/
+
+void CppOutput::output_server_namespace( Namespace& ns, uint32_t indlev )/*{{{*/
+{
+    // First output the Header namespaces for server base class and implementation
+    string ind = get_inds(indlev);
+
+    shout << ind << "namespace " << ns.id << ENDL << ind << "{" << ENDL;
+    scout << ind << "namespace " << ns.id << ENDL << ind << "{" << ENDL;
+
+    list<NamespaceItem*>::iterator nit( ns.items.begin() );
+
+    ++indlev;
+    for(; nit != ns.items.end(); ++nit )
+    {
+	switch( (*nit)->get_namespaceitem_type() )
+	{
+	    case namespace_t:
+		output_server_namespace(dynamic_cast<Namespace&>(**nit),indlev);
+		break;
+	    case class_t:
+		output_server_class(dynamic_cast<Class&>(**nit),0);
+		break;
+	    case enum_t:
+//		output_server_enum((Enum&)**nit,indlev);
+		break;
+	    default:
+		throw runtime_error("Invalid type for NamespaceItem");
+	}
+    }
+    shout << ind << "} // of namespace " << ns.id << ENDL;
+    scout << ind << "} // of namespace " << ns.id << ENDL;
+}/*}}}*/
+
+void CppOutput::output_server_classcommon( Class& c, uint32_t indlev )/*{{{*/
+{
+    scout << "iwear::net::RPCStream* " << c.id << "_Server::_resolve_call( uint32_t crcid, uint32_t version_id, iwear::net::RPCStream* rpcs)" << ENDL;
+    scout << "{" << ENDL;
+    // Sort them all by their crcid ...
+
+    multimap<uint32_t,Function*> crcf;
+    list<ClassItem*>::iterator cit( c.items.begin() );
+    ++indlev;
+    for(; cit != c.items.end(); ++cit)
+    {
+	switch( (*cit)->get_classitem_type() )
+	{
+	    case function_cit:
+		{
+		    Function* f = dynamic_cast<Function*>(*cit);
+		    crcf.insert(make_pair(f->crcid,f));
+		}
+	    default:
+		break;
+	}
+    }
+
+
+    multimap<uint32_t,Function*>::iterator mit(crcf.begin());
+
+    string inds1 = get_inds(1);
+    string inds2 = get_inds(2);
+    string inds3 = get_inds(3);
+    string inds4 = get_inds(4);
+    string inds5 = get_inds(5);
+
+    scout << inds1 << "switch( crcid )" << ENDL;
+    scout << inds1 << "{" << ENDL;
+    
+    uint32_t cid = 0;
+    bool sblock = false;
+
+    multimap<uint32_t,Function*>::iterator nit;
+    for(; mit != crcf.end(); ++mit )
+    {
+	nit = mit;
+	++nit;
+
+	Function* f = mit->second;
+	Function* nf = NULL;
+	if ( nit != crcf.end() )
+	{
+	    nf = nit->second;
+	}
+	else
+	{
+	    nf = NULL;
+	}
+#define CALL(i,f,x) \
+scout << i << "return _resolve_" << hex << f->crcid << "_" << x << "( rpcs );" << ENDL;
+
+	if ( f->crcid == cid || (nf && f->crcid == nf->crcid) )
+	{
+	    if ( ! sblock )
+	    {
+		scout << inds2 << "case 0x" << hex << f->crcid << ":" << ENDL;
+		scout << inds3 << "switch( version_id )" << ENDL;
+		scout << inds3 << "{" << ENDL;
+	    }
+	    scout << inds4 << "case 0x" << hex << f->version_id << ":" << ENDL;
+	    if ( c.version_id == f->version_id )
+	    {
+		scout << inds4 << "default:" << ENDL;
+		CALL(inds5,f,f->id);
+	    }
+	    else
+	    {
+		CALL(inds5,f,f->versioncall);
+	    }
+	    sblock = true;
+	}
+	else
+	{
+	    if ( sblock )
+	    {
+		scout << inds3 << "}" << ENDL;
+	    }
+	    scout << inds2 << "case 0x" << hex << f->crcid << ":" << ENDL;
+	    CALL(inds3,f,f->id);
+	    sblock = false;
+	}
+	cid = f->crcid;
+    }
+    if ( sblock )
+    {
+	scout << inds3 << "}" << ENDL;
+    }
+    scout << inds2 << "default:" << ENDL;
+
+    list<SubClass>& scl = c.subclasses;
+    list<SubClass>::iterator scit( scl.begin() );
+    if ( scl.size() )
+    {
+	scout << inds3 << "iwear::net::RPCStream* rets;" << ENDL;
+    }
+    for(; scit != scl.end(); ++scit )
+    {
+	scout << inds3 << "rets = " << scit->d_class->id << "_Server::_resolve_call(crcid,version_id,rpcs);" << ENDL;
+	scout << inds3 << "if ( rets ) return rets;" << ENDL;
+    }
+    scout << inds3 << "return NULL;" << ENDL;
+//    scout << inds3 << "throw runtime_error(\"Invalid crcid for function, interface mismatch ?\");" << ENDL;
+    scout << inds1 << "}" << ENDL;
+    scout << "}" << ENDL;
+    scout << ENDL;
+/* this is now in bas class and therefore not needed per-object anymore
+    scout << "void " << c.id << "_Server::do_call( iwear::net::RPCStream* rpcs)" << ENDL;
+    scout << "{" << ENDL;
+    scout << inds1 << "uint32_t cid = rpcs->get_uint32_t();" << ENDL;
+    scout << inds1 << "uint32_t vid = rpcs->get_uint32_t();" << ENDL;
+    scout << inds1 << "_resolve_call(cid,vid,rpcs);" << ENDL;
+    scout << "}" << ENDL;
+*/
+    scout << ENDL;
+}/*}}}*/
+
+void CppOutput::output_server_class( Class& c, uint32_t indlev )/*{{{*/
+{
+    last_prot = private_t;
+    // First, output server header definition...
+    string inds = get_inds(indlev);
+    string inds2 = get_inds(indlev+1);
+
+    // output class <ourclassname>_Client : public <ourclassname>
+    shout << inds << "class " << c.id << "_Server";
+    shout << " : public virtual " << c.id;
+    if ( c.subclasses.size() )
+    {
+	list<SubClass>::iterator it = c.subclasses.begin();
+	for ( ; it != c.subclasses.end(); ++it)
+	{
+	    shout << ", " << ENDL;
+	    shout << inds2;
+	    output_derivation(shout,it->d_t);
+	    if ( it->d_t != public_virtual_d &&
+		    it->d_t != protected_virtual_d &&
+		    it->d_t != private_virtual_d )
+	    {
+		shout << "virtual ";
+	    }
+
+	    /*
+	    if ( it != c.subclasses.begin() )
+	    {
+		cmhout << ", ";
+	    }
+	    */
+	    shout << it->d_class->id << "_Server";
+	}
+	shout << ENDL;
+    }
+    else
+    {
+	shout << ENDL;
+    }
+
+    shout << inds << "{" << ENDL;
+    // Here goes the class definition... all the data members are already here,
+    // just output functions
+    shout << inds2 << "friend class callmanager;" << ENDL;
+    output_protection(shout,protected_t,indlev+1);
+
+    list<ClassItem*>::iterator cit( c.items.begin() );
+    ++indlev;
+    for(; cit != c.items.end(); ++cit)
+    {
+	switch( (*cit)->get_classitem_type() )
+	{
+	    case function_cit:
+		output_server_function(c,dynamic_cast<Function&>(**cit),indlev);
+		break;
+	    case declaration_cit:
+//		output_server_declaration((Declaration&)**cit,indlev);
+		break;
+	    case class_cit:
+		output_server_class(dynamic_cast<Class&>(**cit),indlev);
+		break;
+	    case enum_cit:
+//		output_server_enum((Enum&)**cit,indlev);
+		break;
+	    default:
+		throw runtime_error("ClassItem with wrong item type");
+	}
+    }
+
+    // And after all of them, output the end of the class ;)
+
+    output_server_classcommon(c,indlev);
+    shout << inds2 << "virtual iwear::net::RPCStream* _resolve_call( uint32_t crcid, uint32_t version_id, iwear::net::RPCStream* rpcs);" << ENDL;
+//    shout << inds2 << "virtual size_t get_retminsize(uint32_t cid);" << ENDL;
+//    shout << inds2 << "virtual size_t get_minsize( void );" << ENDL;
+//    shout << inds2 << "virtual size_t get_callminsize(uint32_t cid) { return ";
+//    shout << c.id << "::get_callminsize(cid); }" << ENDL;
+//    shout << inds2 << "virtual void do_call( RPCStream* rpcs );" << ENDL;
+
+
+    shout << inds << "};" << ENDL << ENDL;
+}/*}}}*/
+
+void CppOutput::output_server_function( Class& c, Function& f, uint32_t indlev )/*{{{*/
+{
+    string inds = get_inds(indlev);
+    shout << inds;
+    stringstream hexprefix;
+    hexprefix << hex;
+    hexprefix << f.crcid;
+    string fpr;
+    if ( f.versioncall.length() )
+    {
+	fpr = f.versioncall;
+    }
+    else
+    {
+	fpr = f.id;
+    }
+
+    shout << "iwear::net::RPCStream* _resolve_" << hexprefix.str() << "_" << fpr << "( iwear::net::RPCStream* rpcs );" << ENDL;
+
+    scout << "iwear::net::RPCStream* " << c.id << "_Server::_resolve_";
+    scout << hexprefix.str() << "_" << fpr << "( iwear::net::RPCStream* rpcs )";
+
+    scout << ENDL << "{" << ENDL;
+    // Here we need to get the data out of the stream, and create a new stream
+    // to send back to the client
+    list<FunctionArgument>& fal = f.arguments;
+    list<FunctionArgument>::iterator it = fal.begin();
+
+    string inds1 = get_inds(1);
+    string inds2 = get_inds(2);
+    string inds3 = get_inds(3);
+    string inds4 = get_inds(4);
+
+    uint32_t cnt = 0;
+    stringstream arg;
+
+    fpr += "(";
+    for( ; it != fal.end(); ++ it )
+    {
+	arg.str("");
+	arg << "arg";
+	arg << cnt++;
+	scout << inds1 << it->type->id << " " << arg.str() << ";" << ENDL;
+	if ( it != fal.begin() )
+	{
+	    fpr += ", ";
+	}
+	fpr += arg.str();
+	switch( it->mytype )
+	{
+	    case out_t:
+		// We will give them back to the sender later
+		break;
+	    case inout_t:
+	    case in_t:
+		if ( it->type->builtin() )
+		{
+		    scout << inds1 << arg.str() << " = rpcs->get_" << it->type->id << "();" << ENDL;
+		}
+		else
+		{
+		    scout << inds1 << arg.str() << ".fill_from_clientstream(rpcs);" << ENDL;
+		}
+		break;
+	    default:
+		throw runtime_error("invalid value in switch");
+	}
+    }
+    fpr += ");";
+    scout << inds1;
+    if ( f.return_type.type && f.return_type.type->id != "void" )
+    {
+	scout << f.return_type.type->id << " ret;" << ENDL;
+	scout << inds1 << "ret = ";
+    }
+    else
+    {
+	scout << "/* void */ ";
+    }
+    scout << fpr << ENDL;
+
+    if ( f.is_oneway )
+    {
+	scout << inds1 << "return NULL; // oneway" << ENDL;
+    }
+    else
+    {
+	scout << inds1 << "CallManager* cm = get_callmanager();" << ENDL;
+	scout << inds1 << "iwear::net::RPCStream* rets = cd.rmt.rmcl->rmc->get_stream( get_retminsize(0x"
+		    << hex << f.crcid << "));" << ENDL;
+
+	scout << inds1 << "cm->prepare_packet( cd.rmt.rmcl->rmc, rets, cd.channel , MSG_CODE_CALL_RETURN );" << ENDL;
+	scout << inds1 << "rets->put_uid(cm->get_uid()); // The callers system uid" << ENDL;
+	scout << inds1 << "rets->put_uid(get_uid()); // The uid of the object to be called" << ENDL;
+
+	if ( f.return_type.type && f.return_type.type->id != "void" )
+	{
+	    if ( f.return_type.type->builtin() )
+	    {
+		scout << inds1 << "rets->put_" << f.return_type.type->id << "(ret);" << ENDL;
+	    }
+	    else
+	    {
+		scout << inds1 << "ret.fill_stream_server(rets);" << ENDL;
+	    }
+	}
+	it = fal.begin();
+	cnt = 0;
+	for(; it != fal.begin(); ++it )
+	{
+	    arg.str("");
+	    arg << "arg";
+	    arg << cnt++;
+	    switch( it->mytype )
+	    {
+		case out_t:
+		    // Nothing to do, we dont need to send anything back
+		case in_t:
+		case inout_t:
+		    if ( it->type->builtin())
+		    {
+			scout << inds1 << "rets->put_" << it->type->id << "(" << arg.str() << ");" << ENDL;
+		    }
+		    else
+		    {
+			scout << inds1 << arg.str() << ".fill_stream_server(rets);" << ENDL;
+		    }
+		    break;
+		default:
+		    throw runtime_error("invalid value in switch");
+	    }
+	}
+	scout << inds1 << "return rets;" << ENDL;
+    }
+    
+    scout << "}" << ENDL;
+    scout << ENDL;
+
+} /*}}}*/
+// }}}
+// {{{ Output Client Interface Class Files
+
+void CppOutput::output_client_function( Class& c, Function& f, uint32_t indlev )/*{{{*/
+{
+    // Ok, here output the function.... in the header, its just the name... in
+    // the .cpp its the whole implementation for the client code... !!!
+    string inds = get_inds(indlev);
+
+    chout << inds << "virtual ";
+    output_function(chout,f,"");
+    chout << ";";
+
+    chout << ENDL;
+    // Now goes the implementation of the .cpp file... phew, gonna be complex ;)
+    string inds1 = get_inds(1);
+    string inds2 = get_inds(2);
+    string inds3 = get_inds(3);
+    string inds4 = get_inds(4);
+
+    output_function(ccout,f,c.id + "_Client::");
+    ccout << ENDL << "{" << ENDL;
+    // Here goes the implementation then...
+    // First assemble the parameter stream for the call... then dispatch the
+    // call, with the call id of this function....
+    ccout << inds1 << "CallManager* cm = get_callmanager();" << ENDL;
+    ccout << inds1 << "iwear::net::RPCStream* rpcs = cd.rmt.rmcn->get_stream(";
+    ccout << "get_callminsize( 0x" << hex << f.crcid << "));" << ENDL;
+    ccout << inds1 << "rpcs->start_call( 0x" << hex << f.crcid << ");" << ENDL;
+    ccout << inds1 << "cm->prepare_packet( cd.rmt.rmcn, rpcs, channel_id, MSG_CODE_CALL_OBJECT );" << ENDL;
+
+    ccout << inds1 << "rpcs->put_uid(cm->get_uid()); // The callers system uid" << ENDL;
+    ccout << inds1 << "rpcs->put_uid(get_uid()); // The uid of the object to be called" << ENDL;
+    ccout << inds1 << "rpcs->put_uint32_t(0x" << hex << f.crcid << "); // The Function Call ID" << ENDL;
+
+    uint32_t vid = f.version_id;
+    if ( ! vid && c.version_id )
+    {
+	vid = c.version_id;
+    }
+    ccout << inds1 << "rpcs->put_uint32_t(0x" << hex << vid << "); // The Function Version ID" << ENDL;
+    // Ok, what do we need here ? we have to pass all the in and inout objects...
+    list<FunctionArgument>& fal = f.arguments;
+    list<FunctionArgument>::iterator it = fal.begin();
+
+    for( ; it != fal.end(); ++it )
+    {
+	switch(it->mytype)
+	{
+	    case out_t:
+		// nothing to do for them, we just get them back
+		break;
+	    case inout_t:
+	    case in_t:
+		if ( it->type->builtin() )
+		{
+		    ccout << inds1 << "rpcs->put_" << it->type->id << "(" << it->id << ");" << ENDL;
+		}
+		else
+		{
+		    ccout << inds1 << it->id << ".fill_stream_client(rpcs);" << ENDL;
+		}
+		break;
+	    default:
+		throw runtime_error("invalid value in switch");
+	}
+    }
+
+    // Now that we have everything together...
+    ccout << inds1 << "iwear::net::RPCStream* rets = cm->resolve_call( rpcs, this, cd.rmt.rmcn,";
+    if( f.is_oneway )
+    {
+	ccout << "true";
+    }
+    else
+    {
+	ccout << "false";
+    }
+    ccout << ");" << ENDL;
+    // This was the call... no rets contains the stream with all our data...
+    // the return value, outs and inouts...
+    ccout << ENDL;
+    if ( f.return_type.type && f.return_type.type->id != "void" )
+    {
+	ccout << inds1 << f.return_type.type->id << " retval;" << ENDL;
+	if ( f.return_type.type->builtin() )
+	{
+	    ccout << inds1 << "retval = rets->get_" << f.return_type.type->id << "();" << ENDL;
+	}
+	else
+	{
+	    ccout << inds1 << "retval->fill_from_serverstream(rets);" << ENDL;
+	}
+    }
+
+   /* 
+    list<FunctionArgument>& fal = f.arguments;
+    list<FunctionArgument>::iterator it = fal.begin();
+    */
+    it = fal.begin();
+    uint32_t argnum = 0;
+    for( ; it != fal.end(); ++it )
+    {
+	switch( it->mytype )
+	{
+	    case in_t:
+		// Dont need to do anything for in-only (wont come back)
+		break;
+	    case out_t:
+	    case inout_t:
+		// Should be the same for both...
+		if ( it->type->builtin() )
+		{
+		    if ( it->id == "" )
+		    {
+			ccout << inds1 << "arg" << argnum;
+		    }
+		    else
+		    {
+			ccout << inds1 << it->id;
+		    }
+		    ccout << " = " << "rets->get_" << it->type->id << "();" << ENDL;
+		}
+		else
+		{
+		    if ( it->id == "" )
+		    {
+			ccout << inds1 << "arg" << argnum;
+		    }
+		    else
+		    {
+			ccout << inds1 << it->id;
+		    }
+		    ccout << ".fill_from_rpcstream(rets);" << ENDL;
+		}
+		break;
+	    default:
+		throw runtime_error("invalid value in switch");
+	}
+	argnum++;
+    }
+
+//    ccout << inds1 << "cm->release_rpcstream(rets);" << ENDL;
+    ccout << inds1 << "cd.rmt.rmcn->recycle_stream(rets);" << ENDL;
+
+    
+    if ( f.return_type.type && f.return_type.type->id != "void" )
+    {
+	ccout << inds1 << "return retval;" << ENDL;
+    }
+    else
+    {
+	ccout << inds1 << "return;" << ENDL;
+    }
+    ccout << "}" << ENDL;
+    ccout << ENDL;
+}/*}}}*/
+
+void CppOutput::output_client_class( Class& c, uint32_t indlev )/*{{{*/
+{
+    last_prot = private_t;
+    // First, output client header definition...
+    string inds = get_inds(indlev);
+    string inds2 = get_inds(indlev+1);
+
+    // output class <ourclassname>_Client : public <ourclassname>
+    chout << inds << "class " << c.id << "_Client";
+    chout << " : public virtual " << c.id;
+    if ( c.subclasses.size() )
+    {
+	list<SubClass>::iterator it = c.subclasses.begin();
+	for ( ; it != c.subclasses.end(); ++it)
+	{
+	    chout << ", " << ENDL;
+	    chout << inds2;
+	    output_derivation(chout,it->d_t);
+	    if ( it->d_t != public_virtual_d &&
+		    it->d_t != protected_virtual_d &&
+		    it->d_t != private_virtual_d )
+	    {
+		chout << "virtual ";
+	    }
+	    /*
+	    if ( it != c.subclasses.begin() )
+	    {
+		cmhout << ", ";
+	    }
+	    */
+	    chout << it->d_class->id << "_Client";
+	}
+	chout << ENDL;
+    }
+    else
+    {
+	chout << ENDL;
+    }
+
+
+    chout << inds << "{" << ENDL;
+    // Here goes the class definition... all the data members are already here,
+    // just output functions
+
+    chout << inds2 << "friend class RootArtano;" << ENDL;
+    chout << inds2 << "static ClassProvider _x_c_p;" << ENDL;
+
+    ccout << "ClassProvider " << c.id << "_Client::_x_c_p( 0x";
+    ccout << hex << c.crcid << ", " << c.id << "_Client::instance,0);" << ENDL;
+
+    // dont emit any code, a client cannot resolve a call (it cannot be called)
+    chout << inds2 << "virtual RPCStream* _resolve_call( uint32_t , uint32_t , RPCStream* );" << ENDL;
+    ccout << "RPCStream* " << c.id << "_Client::_resolve_call( uint32_t , uint32_t , RPCStream* )" << ENDL;
+    ccout << "{" << ENDL;
+    ccout << "    THROW(iwlogic_error,(\"Cannot call a client remote object\"));" << ENDL;
+    ccout << "}" << ENDL;
+
+    chout << inds2 << "oid_t tuid;" << ENDL;
+    chout << inds2 << "virtual void set_uid( const uid& u ) { tuid = u; }" << ENDL;
+    chout << inds2 << "virtual const uid& get_uid( void ) const { return tuid; }" << ENDL;
+    chout << inds2 << "virtual const string& get_name( void ) const;" << ENDL;
+    ccout << "const string& " <<  c.id << "_Client::get_name( void ) const" << ENDL;
+    ccout << "{" << ENDL;
+    ccout << "    return \"" << c.id << " at a remote host\";" << ENDL;
+    ccout << "}" << ENDL;
+
+
+    list<ClassItem*>::iterator cit( c.items.begin() );
+    ++indlev;
+    for(; cit != c.items.end(); ++cit)
+    {
+	switch( (*cit)->get_classitem_type() )
+	{
+	    case function_cit:
+		output_client_function(c,dynamic_cast<Function&>(**cit),indlev);
+		break;
+	    case declaration_cit:
+//		output_client_declaration((Declaration&)**cit,indlev);
+		break;
+	    case class_cit:
+		output_client_class(dynamic_cast<Class&>(**cit),indlev);
+		break;
+	    case enum_cit:
+//		output_client_enum((Enum&)**cit,indlev);
+		break;
+	    default:
+		throw runtime_error("ClassItem with wrong item type");
+	}
+    }
+
+    chout << inds << "public:" << ENDL;
+    chout << inds2 << "static RemoteObject* instance( void );" << ENDL;
+
+    ccout << "RemoteObject* " << c.id << "_Client::instance( void )" << ENDL;
+    ccout << "{" << ENDL;
+    ccout << "    return new " << c.id << "_Client;" << ENDL;
+    ccout << "}" << ENDL;
+
+    // And after all of them, output the end of the class ;)
+    chout << inds << "};" << ENDL << ENDL;
+}/*}}}*/
+
+void CppOutput::output_client( TranslationUnit& tu )/*{{{*/
+{
+    ccout << header << ENDL;
+    ccout << "#include \"" << filebase << "client.h\"" << ENDL; 
+    ccout << "#include <iwremote/callmanager.h>" << ENDL;
+    ccout << "#include <iwremote/rpcstream.h>" << ENDL;
+    ccout << ENDL;
+    ccout << ENDL;
+    /** @todo TODO Later here use the full types instead of using */
+    ccout << "using namespace iwear::net;" << ENDL;
+
+    chout << header << ENDL;
+    chout << "#include \"" << filebase << "common.h\"" << ENDL;
+    chout << "#include <iwremote/classprovider.h>" << ENDL;
+    chout << ENDL;
+    chout << ENDL;
+
+    list<Namespace*>& tus = tu.get_namespaces();
+    list<Namespace*>::iterator nit( tus.begin() );
+
+    for(; nit != tus.end(); ++nit )
+    {
+	output_client_namespace(**nit,0);
+    }
+}/*}}}*/
+
+void CppOutput::output_client_namespace( Namespace& ns, uint32_t indlev )/*{{{*/
+{
+    // First output the Header namespaces for client base class and implementation
+    string ind = get_inds(indlev);
+
+    chout << ind << "namespace " << ns.id << ENDL << ind << "{" << ENDL;
+    ccout << ind << "namespace " << ns.id << ENDL << ind << "{" << ENDL;
+
+    list<NamespaceItem*>::iterator nit( ns.items.begin() );
+
+    ++indlev;
+    for(; nit != ns.items.end(); ++nit )
+    {
+	switch( (*nit)->get_namespaceitem_type() )
+	{
+	    case namespace_t:
+		output_client_namespace(dynamic_cast<Namespace&>(**nit),indlev);
+		break;
+	    case class_t:
+		output_client_class(dynamic_cast<Class&>(**nit),0);
+		break;
+	    case enum_t:
+//		output_client_enum((Enum&)**nit,indlev);
+		break;
+	    default:
+		throw runtime_error("Invalid type for NamespaceItem");
+	}
+    }
+    chout << ind << "} // of namespace " << ns.id << ENDL;
+    ccout << ind << "} // of namespace " << ns.id << ENDL;
+}/*}}}*/
+
+// }}}
+// {{{ Output Generic Part Functions
+void CppOutput::output_protection( ostream& out, protection prot, uint32_t indlev)/*{{{*/
+{
+    string indsu = get_inds(indlev-1);
+
+    if ( last_prot != prot )
+    {
+	last_prot = prot;
+	switch(last_prot)
+	{
+	    case private_t:
+		out << indsu << "private:" << ENDL;
+		break;
+	    case protected_t:
+		out << indsu << "protected:" << ENDL;
+		break;
+	    case public_t:
+		out << indsu << "public:" << ENDL;
+		break;
+	    default:
+		throw runtime_error("Invalid switch case");
+	}
+    }
+}/*}}}*/
+
+void CppOutput::output_falist( ostream& out, list<FunctionArgument>& fal )/*{{{*/
+{
+    list<FunctionArgument>::iterator it = fal.begin();
+    if ( fal.size() )
+    {
+	for( ; it != fal.end(); ++it )
+	{
+	    if ( it != fal.begin() )
+	    {
+		out << ", ";
+	    }
+	    switch( it->mytype )
+	    {
+		case in_t:
+		    if ( ! it->type->builtin())
+		    {
+			out << "const ";
+			out << it->type->id;
+			out << "& "; 
+		    }
+		    else
+		    {
+			out << it->type->id << " ";
+		    }
+		    out << it->id;
+		    break;
+		case out_t:
+		    out << it->type->id << "& " << it->id;
+		    break;
+		case inout_t:
+		    out << it->type->id << "& " << it->id;
+		    break;
+		default:
+		    throw runtime_error("invalid value in switch");
+	    }
+	}
+    }
+    else
+    {
+	out << "void";
+    }
+}/*}}}*/
+
+string CppOutput::get_inds( uint32_t indlev )/*{{{*/
+{
+    if( indvec.size() )
+    {
+	if ( indlev < indvec.size() )
+	{
+	    return indvec[indlev];
+	}
+	else if ( indlev > 25 )
+	{
+	    throw runtime_error("Cannot indent more than 25");
+	}
+	else
+	{
+	    /*
+	    cout << "Indvec size : " << indvec.size() << ENDL;
+	    cout << "Requested indlev : " << indlev << ENDL;
+	    */
+	    indvec.resize(indlev+1);
+	    for( unsigned int j = indvec.size()-1; j <= indlev; j++ )
+	    {
+		string inds("");
+		for ( unsigned int i = 0; i < j/2; i++ )
+		{
+		    inds += "\t";
+		}
+		if ( indlev%2 )
+		{
+		    inds += "    ";
+		}
+		indvec[j] = inds;
+	    }
+	    return get_inds(indlev);
+	}
+    }
+    else
+    {
+	indvec.resize(1);
+	indvec[0] = "";
+	return get_inds(indlev);
+    }
+}/*}}}*/
+
+void CppOutput::output_function( ostream& out, Function& f, const string& prfx )/*{{{*/
+{
+    if ( ! f.return_type.type )
+    {
+	out << "void";
+    }
+    else
+    {
+	out << f.return_type.type->id ;
+    }
+
+//    cout << "Function ID : \"" << f.id << "\"" << ENDL;
+//    cout << "Function VC : \"" << f.versioncall << "\"" << ENDL;
+    string fname;
+    if ( f.versioncall.length() )
+    {
+	fname = f.versioncall;
+    }
+    else
+    {
+	fname = f.id;
+    }
+//    cout << "Function FN : \"" << fname << "\"" << ENDL;
+//    cout << ENDL;
+    out << " " << prfx << fname;
+    out << "( ";
+
+    output_falist(out,f.arguments);
+
+    out << " )";
+}/*}}}*/
+// }}}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.16  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.15  2005/09/14 00:57:17  plasmahh
+ * removed redundant
+ *
+ * Revision 1.14  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.13  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.12  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.11  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.10  2005/04/21 19:41:57  plasmahh
+ * after work sync
+ *
+ * Revision 1.9  2005/04/18 20:13:58  plasmahh
+ * lm deregistration done now
+ *
+ * Revision 1.8  2005/04/01 09:04:38  plasmahh
+ * neues für euch zum spielen
+ *
+ * Revision 1.7  2005/02/25 09:09:34  plasmahh
+ * kleinigkeiten
+ *
+ * Revision 1.6  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.5  2005/01/21 23:34:31  plasmahh
+ * more ideas and stuff
+ *
+ * Revision 1.4  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.3  2004/12/05 00:25:40  plasmahh
+ * iwremote stuff
+ *
+ * Revision 1.2  2004/12/03 00:33:20  plasmahh
+ * genug arbeit fuer heude
+ *
+ */
Index: /tags/help/iwearrpc/src/sptrtracker.cpp
===================================================================
--- /tags/help/iwearrpc/src/sptrtracker.cpp (revision 2229)
+++ /tags/help/iwearrpc/src/sptrtracker.cpp (revision 2229)
@@ -0,0 +1,82 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <sptrtracker.h>
+#include <iostream>
+//#include <utility.h>
+//#include <debugstream.h>
+using namespace std;
+
+namespace iwear
+{
+
+SPtrTracker::~SPtrTracker( )    
+{
+//    d_dbg << "CALLING " << __FFL__ << endl;
+//    d_dbg << "Resetting all we know" << endl;
+    ThreadLocker tl(Mutex);
+    dying = true;
+ //   d_dbg << "locked and dying state set" << endl;
+//    d_dbg << "Size of the set is : " << SPtrMap.size() << endl;
+  //  d_dbg << "Now creating iterator" << endl;
+    set<SpecialPointer*>::iterator pit(SPtrMap.begin());
+//    d_dbg << "Now iterating" << endl;
+    for(;pit != SPtrMap.end();pit++)
+    {
+	SpecialPointer* ptr;
+	ptr = (*pit);
+//	d_dbg << "Resetting from " << (void*) ptr << endl;
+	ptr->reset();
+    }
+    SPtrMap.clear(); // Clear the pointer list, just to make sure in case of races...
+}
+
+}
+/**
+ * $Log$
+ * Revision 1.2  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.1  2005/06/30 18:37:30  plasmahh
+ * sync
+ *
+ * Revision 1.6  2005/04/19 12:12:12  plasmahh
+ * ssl changes, typos
+ *
+ * Revision 1.5  2004/09/18 15:20:54  plasmahh
+ * Preparing for MAC Build support
+ *
+ * Revision 1.4  2004/09/12 15:34:52  plasmahh
+ * Still segfaulting :/
+ *
+ * Revision 1.3  2004/07/05 14:01:14  plasmahh
+ * removed this stupid const_cast
+ *
+ * Revision 1.2  2004/07/04 21:33:01  plasmahh
+ * added delete function as a real delete does not work
+ *
+ * Revision 1.1  2004/07/04 20:09:04  plasmahh
+ * added specialpointer and such stuff
+ *
+ */
Index: /tags/help/iwearrpc/src/enum.cpp
===================================================================
--- /tags/help/iwearrpc/src/enum.cpp (revision 1182)
+++ /tags/help/iwearrpc/src/enum.cpp (revision 1182)
@@ -0,0 +1,61 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <enum.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+void Enum::add_enumdef( const EnumDef& ed )
+{
+    /** @todo TODO Check if the def doesnt alread exist */
+    enumdefs.push_back(ed);
+}
+
+string Enum::get_crcstring( void )
+{
+    /// FIXME create a real crcstring here !!!
+    return "xxx";
+}
+
+void Enum::generate_crcids( const string& )
+{
+}
+	
+}
+}
+/**
+ * $Log$
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/src/class.cpp
===================================================================
--- /tags/help/iwearrpc/src/class.cpp (revision 2229)
+++ /tags/help/iwearrpc/src/class.cpp (revision 2229)
@@ -0,0 +1,126 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <class.h>
+#include <iwear/crc.h>
+#include <declaration.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+void Class::add_item( ClassItem& st )
+{
+    st.my_class = this;
+    items.push_back(&st);
+}    
+
+string Class::get_crcstring( void )
+{
+    // Avoid assembling it more than once..
+    if ( crcs.length() ) return crcs;
+    /**
+     * crcstring
+     * 1. all the subclasses crcstrings
+     * 2. my id
+     * 3. all the functions/inner classes crcstrings
+     * 4. NOT the version identifier.
+     * @todo check if we need the namespace identifiers here too. I think not
+     * since its very unlikely that two classes in different namespaces will
+     * have the same CRCID then...
+     */
+    list<SubClass>::iterator lit(subclasses.begin());
+
+    for ( ; lit != subclasses.end(); ++lit )
+    {
+	/// FIXME if the parser does not catch circulars, do it here !
+	crcs += lit->d_class->get_crcstring();
+    }
+
+    crcs += id;
+
+    list<ClassItem*>::iterator cit(items.begin());
+    
+    for( ; cit != items.end(); ++cit )
+    {
+	crcs += (*cit)->get_crcstring();
+    }
+    return crcs;
+}
+
+void Class::generate_own_size( void )
+{
+    data_size = "0";
+    list<ClassItem*>::iterator iti(items.begin());
+
+    for(; iti != items.end(); ++iti )
+    {
+	Declaration* dec = dynamic_cast<Declaration*>(*iti);
+	if( dec )
+	{
+	    data_size += "+";
+	    data_size += dec->get_own_size();
+	}
+    }
+}
+
+void Class::generate_crcids(const string&)
+{
+    generate_own_size();
+    CRC32 crc;
+
+    (void) get_crcstring();
+    crc.process_bytes(crcs.c_str(),crcs.length());
+
+    list<ClassItem*>::iterator cit(items.begin());
+    
+    cit = items.begin();
+    for ( ; cit != items.end(); ++cit )
+    {
+	(*cit)->generate_crcids(crcs);
+    }
+    crcid = crc.checksum();
+}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.5  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.4  2005/04/01 09:04:38  plasmahh
+ * neues für euch zum spielen
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/src/testserver.cpp
===================================================================
--- /tags/help/iwearrpc/src/testserver.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/testserver.cpp (revision 2256)
@@ -0,0 +1,120 @@
+
+extern "C" {
+#include <rpc/xdr.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+}
+
+#include <iwremote/rootartano.h>
+#include <iwear/debugstream.h>
+#include <iwear/configuration.h>
+#include <iwear/shmemory.h>
+#include <iwear/servicemanager.h>
+#include <iwear/sysvsemaphore.h>
+#include <iwear/tcpconnection.h>
+#include <iwear/utility.h>
+#include <iwremote/callmanager.h>
+#include <iwremote/class.h>
+#include <iwremote/cppoutput.h>
+#include <iwremote/declaration.h>
+#include <iwremote/enum.h>
+#include <iwremote/function.h>
+#include <iwremote/idloutput.h>
+#include <iwremote/namespace.h>
+#include <iwremote/translationunit.h>
+#include <iwremote/xdrstream.h>
+#include <iwremote/socketprovider.h>
+#include <../testserver.h>
+#include <iwear/buildphase.h>
+
+#include <iostream>
+using namespace std;
+using namespace iwear;
+using namespace iwear::net;
+using namespace iwear::sensor;
+
+class RDSI: public RemoteDataSensor_Server
+{
+public:
+    uid myuid;
+    string name;
+    RDSI( const string& t ) : myuid(t), name(t) 
+    { 
+	test = 0;
+	_M_data = 0.1;
+    }
+    virtual const uid& get_uid( void ) const { return myuid; }
+    virtual const string& get_name( void ) const { return name; }
+
+    // thats the funcition of the interface to be implemented
+    virtual void trigger(double x) { cout << "CALLED TRIGGER WITH " << x << endl; }
+
+};
+
+int main ( void )
+{
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+    d_err.set_debuglevel(nonsens);
+
+    BuildPhase::build_phase = 1;
+//    enable_verbose_crash();
+
+    RDSI rdsi("testuid");
+    cout << "rdsi uid: " << rdsi.get_uid() << endl;
+
+
+    try
+    {
+	Configuration conf;
+	ServiceManager SM(conf);
+	RootArtano RA(&SM);
+	// TODO FIXME this needs to be done in the autogenerated stuff
+	RA.register_object(rdsi.get_uid(), &rdsi);
+	CallManager& cman = RA.get_callmanager();
+
+	SocketProvider sprov(&cman);
+
+	cman.add_callprovider(&sprov);
+
+	RA.Init();
+	cout << "host uid: " << cman.get_uid() << endl;
+//	cout << cm->get_name() << " : " << cm->get_uid() << endl;
+	cout << "Ok, we are running and hopefully ready to accept connections..." << endl;
+	usleep(1000000000);
+	usleep(1000000000);
+	usleep(1000000000);
+	usleep(1000000000);
+	usleep(1000000000);
+    }
+    catch( const exception& e )
+    {
+	cout << "Catched Exception:" << endl;
+	cout << e << endl;
+	usleep(1000000000);
+    }
+
+    /*
+    delete new SysVSemaphore(1,2,3);
+
+    SysVSemaphore sem(1,0,1);
+    cout << "SEM VALUE " << sem.Value() << endl;
+    errno = 0;
+    cout << "RET " << sem.Post() << flush; perror(" " );
+    cout << "SEM VALUE " << sem.Value() << endl;
+    errno = 0;
+    cout << "RET " << sem.Post() << flush; perror(" " );
+    cout << "SEM VALUE " << sem.Value() << endl;
+    errno = 0;
+    cout << "RET " << sem.Wait() << flush; perror(" " );
+    cout << "SEM VALUE " << sem.Value() << endl;
+
+    usleep(1000000000);
+    usleep(1000000000);
+    usleep(1000000000);
+    usleep(1000000000);
+*/
+}
Index: /tags/help/iwearrpc/src/callmanager.cpp
===================================================================
--- /tags/help/iwearrpc/src/callmanager.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/callmanager.cpp (revision 2256)
@@ -0,0 +1,839 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <callmanager.h>
+#include <iwear/socketconnection.h>
+#include <iwear/hash.h>
+#include <iwear/i18n.h>
+#include <iwear/sysvsemaphore.h>
+#include <iwear/debugstream.h>
+#include <iwear/crc.h>
+#include <iwear/scopetracer.h>
+#include <remoteobject.h>
+#include <remoteconnection.h>
+#include <remotecaller.h>
+#include <xdrstream.h>
+#include <callprovider.h>
+#include <protocol.h>
+#include <rootartano.h>
+//#include <shmstream.h>
+//#include <nullstream.h>
+
+extern "C"
+{
+#include <signal.h>
+}
+
+
+namespace iwear
+{
+    namespace net
+    {
+
+CallManager::~CallManager()
+{
+    ScopeTracer st(__FFL__);
+ /*   
+    cout << __FFL__ << endl;
+    cout << "Destroying CallManager at " << (void*) this <<  endl;
+    cout << "Actual state is " << actual_state << endl;
+    cout << "Actual state is at " << (void*)&actual_state << endl;
+    void * dst = (void*)actual_state;
+    cout << "Actual state as pointer "  << dst << endl;
+    cout << " pthread_self() == "  << pthread_self() << endl;
+    abort();
+    */
+    delete sem;
+}
+
+CallManager::CallManager( ServiceManager* SM, RootArtano* ra)
+    : Service(SM), RA(ra), mm ("dummy",1), sem(NULL)
+{
+    ScopeTracer st(__FFL__);
+    /*
+    cout << __FFL__ << endl;
+    cout << "Created CallManager at " << (void*) this <<  endl;
+    cout << "Actual state is " << actual_state << endl;
+    cout << "Actual state is at " << (void*)&actual_state << endl;
+    cout << " pthread_self() == "  << pthread_self() << endl;
+    */
+}
+
+oid_t CallManager::service_only_oid(0,0);
+
+void CallManager::Init( void )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    ThreadLocker tl( Mutex );
+    d_dbg << "Starting CallManager Init" << endl;
+
+    // Ok, what do we need here ?
+    // 1. initialize some kind of shm segment for local shortcut-calling
+    // 2. probably allocate the socket, if not done within Start, dont know yet.
+    // 3. Get the HW Adress and form the hosts uid out of it.
+    if ( actual_state == sstate_created )
+    {
+	try
+	{
+	    string hwaddr;
+	    ///@todo TODO check if something like if_indextoname is better for
+	    ///getting an appropriate interface which has a hw address... like
+	    ///loop through all indices, and take the first iface with hwaddr
+	    try
+	    {
+		hwaddr = SocketConnection::get_hwaddr("eth0");
+	    }
+	    catch(...)
+	    {
+		try
+		{
+		    hwaddr = SocketConnection::get_hwaddr("eth1");
+		}
+		catch(...)
+		{
+		    try
+		    {
+			hwaddr = SocketConnection::get_hwaddr("wlan0");
+		    }
+		    catch(...)
+		    {
+			    hwaddr = SocketConnection::get_hwaddr("wlan1");
+
+		    }
+		}
+	    }
+	    MD5Hash hsh;
+	    hsh.From(hwaddr);
+	    uid u(hsh.getHashcode());
+	    ID = u;
+	    cout << "CALLMANAGER UID:" << u << endl;
+	    cout << "CALLMANAGER UID:" << ID << endl;
+	    stringstream s;
+
+	    s << u;
+	    string shmkey = s.str();
+
+	    /**
+	     * @todo TODO make this here some configurable security option,
+	     * maybe we want this segment to be open for everyone... (then we
+	     * should also try to make the segment readable & writable by
+	     * others in the SHMemory ;)
+	     */
+	    char * user = getenv("USER");
+	    shmkey += "_";
+	    shmkey += user;
+	    SHMemory jm(shmkey,SHM_SIZE);
+	    mm.unlink();
+	    mm = jm;
+
+	    CRC32 crc;
+	    crc.process_bytes(shmkey.c_str(),shmkey.length());
+	    uint32_t skey = crc.checksum();
+	    delete new SysVSemaphore(skey,10,1); // To initially create 10 semaphores with count 0
+//	    system("ls -la /dev/shm/");
+	    sem = new SysVSemaphore(skey,1,1);
+	    // look if we need to recover...
+	    pid_t lp = sem->LastPid();
+	    cout << "Last accessed pid is " << lp << endl;
+	    /**
+	     * @todo TODO what do we do if there is still someone holding the
+	     * semaphore but not yet has touched it so that the pid_t is not
+	     * yet updated ? 
+	     */
+	    if ( kill(lp,0) )
+	    {
+		cout << "Last work on semaphore done from not existing process, recovering" << endl;
+		sem->SetValue(1);
+		// Also recover the shm segment, it does not seem to be used by someone...
+		memset(mm,0,SHM_SIZE);
+	    }
+	    actual_state = sstate_stopped;
+	}
+	catch(...)
+	{
+	    actual_state = sstate_created;
+	    throw;
+	}
+    }
+    else
+    {
+	throw invalidstate_error(__PRETTY_FUNCTION__);
+    }
+}/*}}}*/
+
+void CallManager::Start( void )
+{
+    ScopeTracer st(__FFL__);
+    d_dbg << "Starting up CallManager" << endl;
+    ThreadLocker tl( Mutex );
+    if ( actual_state == sstate_stopped )
+    {
+	try
+	{
+	    actual_state = sstate_started;
+	    Thread::Start();
+	}
+	catch(...)
+	{
+	    actual_state = sstate_error;
+	    throw;
+	}
+    }
+    else
+    {
+	cout << "State is " << actual_state << endl;
+	throw invalidstate_error(__PRETTY_FUNCTION__);
+    }
+}
+
+void CallManager::Stop( void )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+}
+
+void CallManager::Reset( void )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+}
+
+void CallManager::Suspend( void )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+}
+
+void CallManager::Pause( void )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+}
+
+void CallManager::Resume( void )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+}
+
+void CallManager::_debug_print_state( void )
+{
+    d_dbg << ANSI_RED << "############################ CALL MANAGER STATE ############################" << endl;
+    d_dbg << ANSI_BLUE << "Host UID:" << ANSI_VIOLET << sysuid << endl;
+    d_dbg << ANSI_BLUE << "Service UID: " << ANSI_VIOLET << service_only_oid << endl;
+
+    d_dbg << ANSI_BLUE << "RootArtano: " << ANSI_NORMAL << (void*)RA << "(disabled to avoid recursion)" << endl;
+
+    d_dbg << ANSI_BLUE << "host_list: " << ANSI_NORMAL << host_list.size() << endl;
+    multimap<const hostid_t*, HostConnector, deref_less<const hostid_t*> >::iterator hli(host_list.begin());
+    for(; hli != host_list.end(); ++hli)
+    {
+    d_dbg << ANSI_VIOLET << *(hli->first) << ANSI_YELLOW << "==>" << ANSI_VIOLET << *(hli->second.hostid) << endl;
+    }
+    
+    d_dbg << ANSI_BLUE << "connection_cache: " << ANSI_NORMAL << connection_cache.size() << endl;
+    multimap<RemoteConnectionPtr, triple<uid,uint32_t,string> >::iterator cci(connection_cache.begin());
+    for(; cci != connection_cache.end(); ++cci )
+    {
+	d_dbg << ANSI_BLUE << cci->first << cci->second.first << cci->second.second << cci->second.third << endl;
+    }
+
+    d_dbg << ANSI_BLUE << "oid_cache: " << ANSI_NORMAL << oid_cache.size() << endl;
+    map<const oid_t*, RemoteConnectionPtr, deref_less<const oid_t*> >::iterator oi(oid_cache.begin());
+
+    for(; oi != oid_cache.end(); ++oi )
+    {
+	d_dbg << (oi->first) << oi->second << endl;
+    }
+
+    d_dbg << ANSI_BLUE << "Call Providers:" << ANSI_NORMAL << cps.size() << endl;
+    set<CallProvider*>::iterator cpi( cps.begin());
+
+    for( ; cpi != cps.end(); ++cpi )
+    {
+	(*cpi)->_debug_print_state();
+    }
+}
+
+void CallManager::check_callproviders( void )
+{
+    ScopeTracer st(__FFL__);
+    set<CallProvider*>::iterator ci(cps.begin());
+    
+    for(; ci != cps.end(); ++ci )
+    {
+	try
+	{
+	    CallProvider* cp = dynamic_cast<CallProvider*>(*ci);
+
+	    (*ci)->check_channels();
+
+	    // Allow only 10msecs of timeout to check so we are shure to check all
+	    // others frequently enough. 10msecs is one Linux standard timeslice so
+	    // this should only execute once per timeslice in average
+	    pair<RPCStream*,RemoteConnectionPtr> inc = (*ci)->get_system_stream(0.01);
+	    if( inc.first )
+	    {
+		d_dbg << "Incoming RCPStream : " << (void*)inc.first << endl;
+		try
+		{
+		    process_incoming_stream(inc.first,inc.second);
+		}
+		catch( const protocol_error& p )
+		{
+		    inc.second->handle_error(p);
+		}
+		catch( const exception& e )
+		{
+		    d_err << "Exception in internal processing" << endl;
+		    throw;
+		}
+	    }
+	}
+	catch(const exception& e )
+	{
+	    d_warn << "Exception occured in processing of incoming data stream" << endl;
+	    d_warn << e << endl;
+	    _debug_print_state();
+	    //TODO what do we do with the stream now ?
+	}
+    }
+}
+
+void CallManager::Run( void )
+{
+    ScopeTracer st(__FFL__);
+
+    while ( actual_state != sstate_stopped &&
+	    actual_state != sstate_error )
+    {
+	ScopeTracer st(__FFL__);
+	TestCancel();
+	check_callproviders();
+	///FIXME we should sleep only if the queues were emptied last run.
+	usleep(1000);
+    }
+}
+
+void CallManager::add_callprovider( CallProvider* cp )
+{
+    ScopeTracer st(__FFL__);
+    cps.insert(cp);
+}
+
+const string CallManager::get_name( void )
+{
+    ScopeTracer st(__FFL__);
+    P1CLEAR
+    return i18n::trans("RPC Call Manager");
+}
+
+RPCStream* CallManager::resolve_call( RPCStream* rpcs, RemoteObject* ro, 
+	RemoteConnectionPtr rcon, bool oneway )
+{
+    ScopeTracer st(__FFL__);
+
+    // In case its a deffered connected, or we lost connectivity
+    if( ! rcon->is_connected() )
+    {
+	rcon->reconnect(); // Let exceptions propagate
+    }
+    if( ! rcon->is_connected() )
+    {
+	THROW(connlost_error,("Cannot establish connection to host",-1));
+    }
+    // Now we are connected, finish the packet
+    finish_packet(rpcs);
+    rcon->send_rpcpacket(rpcs);
+    if( ! oneway )
+    {
+	rcon->wait_for_channel( ro->channel_id );
+	RPCStream* rpret = rcon->get_stream(0);
+	rcon->receive_rpcpacket( *rpret, ro->channel_id );
+
+	uint8_t tpe = check_packet_error(rpret,ro->channel_id);
+	if( MSG_CODE_CALL_RETURN == tpe )
+	{
+	    return rpret;
+	}
+	else
+	{
+	    THROW(protocol_error,("Invalid packet type at this point",ro->channel_id,MSG_REASON_UNSUPPORTED,0));
+	}
+    }
+    else
+    {
+	return 0;
+    }
+}
+
+uint8_t CallManager::check_packet_error( RPCStream* rpcs, chanid_t chan )
+{
+    d_dbg << __FFL__  << endl;
+    uint8_t type = skip_header( rpcs );
+    switch(type)
+    {
+	case MSG_CODE_ERROR:
+	    {
+		uint32_t err = rpcs->get_uint32_t();
+		switch(err)
+		{
+		    case MSG_REASON_UNDEFINED:
+			THROW(protocol_error,("No Reason Specified",chan,err,0));
+		    case MSG_REASON_NOCID:
+			THROW(protocol_error,("No such ClassID",chan,err,0));
+		    case MSG_REASON_NOUID:
+			THROW(protocol_error,("No such UID",chan,err,0));
+		    case MSG_REASON_NOCUID:
+			THROW(protocol_error,("No such ClassID with desired UID",chan,err,0));
+		    case MSG_REASON_NOCHAN:
+			THROW(protocol_error,("No such channel",chan,err,0));
+		    case MSG_REASON_SECURITY:
+			THROW(protocol_error,("Security prevented",chan,err,0));
+		    case MSG_REASON_DEFECT:
+			THROW(protocol_error,("Packet defect detected",chan,err,0));
+		    case MSG_REASON_INTERNAL:
+			THROW(protocol_error,("Internal Error",chan,err,0));
+		    case MSG_REASON_UNSUPPORTED:
+			THROW(protocol_error,("Operation not supported",chan,err,0));
+		    case MSG_REASON_BUFFER:
+			THROW(protocol_error,("Buffer problems",chan,err,0));
+		    default:
+			THROW(protocol_error,("Unknown Error Code",chan,err,0));
+		}
+	    }
+	    break;
+	case MSG_CODE_CALL_ERROR:
+	    {
+		string rsn = rpcs->get_string();
+		THROW(remote_error,(rsn));
+	    }
+	case MSG_CODE_CALL_RETURN:
+	default:
+	    //Maybe its unknown and therefore we just return
+	    return type;
+    }
+}
+
+uint8_t CallManager::skip_header( RPCStream* rpcs )
+{
+    rpcs->reset();
+    uint8_t flags = rpcs->get_uint8_t();
+    uint8_t type = rpcs->get_uint8_t();
+    (void)rpcs->get_uint16_t();
+    if( flags & MSG_FLAG_SEQ )
+    {
+	(void) rpcs->get_uint32_t();
+    }
+    return type;
+}
+
+RPCStream& CallManager::get_association_return( RemoteConnectionPtr rc , const uid& id, chanid_t chan_id )
+{
+    ScopeTracer st(__FFL__);
+    
+    map<pair<RemoteConnectionPtr,chanid_t>, RPCStream* >::iterator wi(waiting_associations.end());
+
+    while( (wi = waiting_associations.find(make_pair(rc,chan_id))) == waiting_associations.end() )
+    {
+	///FIXME need some timeout on global waiting
+	usleep(1000);
+    }
+    RPCStream& rpcs = *(wi->second);
+
+    return rpcs;
+
+    // Wait until an message with the correct channel ID comes in...
+    // The Message will come in on the SystemChannel, and System Messages should be serialized...
+    
+    //Ok, someone is waiting for a association return on this line, lets see
+    //what comes in and what we need to do with it.
+}
+
+RemoteConnectionPtr CallManager::get_responsible_connection( const oid_t& id ) const/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    d_dbg << ANSI_BLUE << "Starting search to find a connection suitable for given oid_t" << ANSI_NORMAL << endl;
+    // Search in our oid_t->Connection cache for a connection that can handle this oid_t
+    map<const oid_t*, RemoteConnectionPtr, deref_less<const oid_t*> >::const_iterator ut(oid_cache.find(&id));
+    if( ut != oid_cache.end() )
+    {
+	d_dbg << ANSI_GREEN << "Found a suitable connection for the oid_t" << ANSI_NORMAL << endl;
+	return ut->second;
+    }
+    else
+    {
+	d_dbg << ANSI_YELLOW << "Did not find a suitable connection for an oid_t" << ANSI_NORMAL << endl;
+	return 0;
+    }
+}/*}}}*/
+
+RemoteConnectionPtr CallManager::get_connection_to_host( const hostid_t& id )
+{
+    ScopeTracer st(__FFL__);
+    // Check if we know a connection to the specified host, if not do one
+
+    // first search in the host_list
+    multimap<const uid*, HostConnector, deref_less<const uid*> >::iterator hi(host_list.find(&id));
+
+    if( hi != host_list.end() )
+    {
+	return hi->second.condis->get_connection();
+	// Ok, we found information on how to connect to the stuff
+    }
+    else
+    {
+	d_dbg << ANSI_YELLOW << "Sorry dont have cached any information on how to connect to host ";
+	d_dbg << ANSI_VIOLET << id << ANSI_NORMAL << endl;
+	return 0;
+    }
+}
+
+multimap<RemoteDescriptor*,HostConnector> CallManager::search_providing_host( const uid& o_id, search_behaviour sb)
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+}
+
+///@todo TODO find a way to "piggyback" the actual call request to this packet
+//to optimize data flow, maybe add an overloaded call ?
+uint16_t CallManager::send_associate_request( RemoteConnectionPtr& rc, const uid& id, uint32_t crcid )
+{
+    // Here we assume that the crcid is either valid or that it is 0
+    ScopeTracer st(__FFL__);
+
+    //TODO this is the point where the mechanism should be added that chooses
+    //whether we use the existing connection or establish a new one. The
+    //CallProvider which created the actual connetion whould be asked for it,
+    //since it will best know about connection quality etc.
+
+    RPCStream* rpcs = rc->get_stream( SIZE_HEADER + SIZE_UID + SIZE_UID + SIZE_WORD /*+ ???*/);
+
+    uint16_t prechan = rc->preallocate_channel();
+
+    prepare_packet( rc,rpcs,prechan,MSG_CODE_ASSOCIATE);
+
+    rpcs->put_uid(get_uid());
+    rpcs->put_uid(id);
+    rpcs->put_uint32_t(crcid);
+
+    finish_packet( rpcs ); // after this the packet might be at any position !
+
+    rc->send_rpcpacket(rpcs);
+    rc->recycle_stream(rpcs);
+    return prechan;
+}
+
+void CallManager::finish_packet( RPCStream* rpcs )
+{
+    ///@todo TODO do we need to do more, like setting some flags etc. ?
+    rpcs->reset();
+    rpcs->put_uint32_t(rpcs->get_buffer().second);
+}
+
+void CallManager::check_security_provider( RemoteConnectionPtr rcon, const hostid_t& hid, const oid_t& oid )
+{
+    ScopeTracer st(__FFL__);
+    set<SecurityProvider*>::iterator spi(security_providers.begin());
+
+    for(; spi != security_providers.end(); ++spi )
+    {
+	if( ! (*spi)->check_host(rcon,hid) )
+	{
+	    THROW(protocol_error,("host on this connection is blacklisted",0,MSG_REASON_SECURITY,0));
+	}
+    }
+    spi = security_providers.begin();
+
+    for(; spi != security_providers.end(); ++spi )
+    {
+	if( ! (*spi)->check_object(rcon,hid,oid) )
+	{
+	    THROW(protocol_error,("object2host on this connection is blacklisted",0,MSG_REASON_SECURITY,0));
+	}
+    }
+
+}
+
+void CallManager::object_associate( RemoteConnectionPtr rc, uint16_t chan, const hostid_t& hid, const oid_t& oid, cid_t cid )
+{
+    ScopeTracer st(__FFL__);
+    cout << ANSI_RED << "object associateion wanted" << endl;
+    cout << ANSI_GREEN << "Host ID: " << ANSI_BLUE << hid << endl;
+    cout << ANSI_GREEN << "Object ID: " << ANSI_BLUE << oid << endl;
+    cout << ANSI_GREEN << "Class ID: " << ANSI_BLUE << cid << ANSI_NORMAL << endl;
+
+    // only the master side is allowed to create channel ids
+    if( chan && rc->is_master() )
+    {
+	THROW(protocol_error,("chanid sent to master side",chan,MSG_REASON_DEFECT,0));
+    }
+    //ok, look if we have this object, then apply security stuff and after that
+    //do whatever is needed ;)
+
+    check_security_provider( rc, hid, oid );
+    if( oid == service_only_oid )
+    {
+	// Ok, the caller does not want a specific oid, just the service, so
+	// look just for a object with this service (maybe we can instantiate
+	// one if needed )
+	UNIMPLEMENTED
+    }
+    //mk, the security did not throw so, we can continue... lets look if we have the object
+    RemoteObject* ro = RA->get_object( oid );
+
+    if( ! ro ) THROW(protocol_error,("No such object known",chan,MSG_REASON_NOUID,0));
+
+    //mk, we have a ro check if it implements the cid
+    if( ! ro->implements(cid) && cid != 0 ) THROW(protocol_error,("This uid does not have this cid",chan,MSG_REASON_NOCUID,0));
+
+    //ok, looks like it has passed security checks, we have a matching object,
+
+    // look for a valid channel (the functions will throw if something goes wrong)
+    chanid_t ch;
+    if( rc->is_master() )
+    {
+	ch = rc->preallocate_channel();
+    }
+    else
+    {
+	ch = chan;
+	// The channel should have been already preallocated by the
+	// RemoteConnection upon receival
+
+//	rc->preallocate_channel(chan);
+    }
+    // XXX this point is for additional checks before final allocation of channel
+    // mk, we have a channel, completely allocate it
+
+    // now internally associate the object
+    rc->allocate_channel(ro,ch);
+
+    // tell the caller were successfull
+    send_associate_return( hid, rc, ro, ch );
+}
+
+void CallManager::prepare_packet( RemoteConnectionPtr rcon, RPCStream* rpcs, chanid_t ch, uint8_t tp )
+{
+    ScopeTracer st(__FFL__);
+    rpcs->put_uint32_t(0); // Reserve header bytes
+    rpcs->put_uint8_t(0); // Reserve flag byte
+    rpcs->put_uint8_t( tp );
+    rpcs->put_uint16_t( ch );
+
+    if( rcon->next_sequence() )
+    {
+	rpcs->put_uint32_t( rcon->next_sequence() );
+    }
+    // Packet is ready
+}
+
+void CallManager::send_associate_return( const hostid_t& hi, RemoteConnectionPtr rcon, RemoteObject* ro, chanid_t ch )
+{
+    ScopeTracer st(__FFL__);
+    vector<cid_t>cids = ro->get_cid();
+    ///XXX need good mechanism to make calculating the stream size easier (like
+    //a template class ;) ?)
+    RPCStream* rpcs = rcon->get_stream( 4+4+4+16+16+4 + 4*cids.size()  + ro->get_minsize() );
+
+    prepare_packet(rcon,rpcs,ch,MSG_CODE_ASS_RETURN);
+    rpcs->put_uid(hi);
+    rpcs->put_uid(ro->get_uid());
+
+    d_dbg << "inserting " << cids.size() << " cids into the return" << endl;
+    rpcs->put_uint16_t(cids.size());
+
+    for( size_t i = 0; i < cids.size(); ++i )
+    {
+	rpcs->put_uint32_t(cids[i]);
+    }
+    ro->fill_stream_server(rpcs);
+    finish_packet(rpcs);
+    // anything else needed ? hm, no.
+    rcon->send_rpcpacket(rpcs);
+    rcon->recycle_stream(rpcs);
+}
+
+void CallManager::handle_error( RemoteConnectionPtr rc, uint32_t reason, uint16_t chan )
+{
+    d_dbg << "Handling error: " << dec << reason << " on chan " << chan << endl;
+    d_dbg << iwexception::backtrace() << endl;
+    switch(reason)
+    {
+	case MSG_REASON_BUFFER:
+	    d_dbg << ANSI_BLUE << "System says there is no buffer space for the desired operation" << endl;
+	    d_dbg << ANSI_NORMAL;
+	    break;
+	case MSG_REASON_INTERNAL:
+	    d_dbg << ANSI_BLUE << "Remote System internal error, aborint" << endl;
+	    rc->disconnect();
+	    break;
+	case MSG_REASON_NOCHAN:
+	    d_dbg << ANSI_BLUE << "Hm, the remote system says there is no such channel: " << chan << ANSI_NORMAL << endl;
+	    break;
+	default:
+	    break;
+    }
+}
+
+void CallManager::finish_associate( RemoteConnectionPtr rc, RPCStream* rpcs, uint16_t chan )
+{
+    ScopeTracer st(__FFL__);
+    // we are probably in another thread that has called a
+    // get_association_return on us.
+    waiting_associations.insert(make_pair(make_pair(rc,chan),rpcs));
+}
+
+RPCStream* CallManager::do_call( const oid_t& ob, const hostid_t& ho, RemoteConnectionPtr rc, 
+	chanid_t chan, uint32_t func, uint32_t fver)
+{
+    d_dbg << "do_call on channel " << chan << " for function 0x" << hex << func << endl;
+    UNIMPLEMENTED
+}
+
+void CallManager::process_incoming_stream( RPCStream* rpcs, RemoteConnectionPtr rc )
+{
+    ScopeTracer st(__FFL__);
+    //XXX is it possible to avoid this additional "parsing" of the stream ?
+    rpcs->reset();
+    uint8_t flags = rpcs->get_uint8_t();
+    uint8_t type = rpcs->get_uint8_t();
+    uint16_t chan = rpcs->get_uint16_t();
+    
+//    d_dbg << "flags = 0x" << hex << (uint32_t)flags << endl;
+//    d_dbg << "flags | MSG_FLAG_SEQ = 0x" << hex <<(uint32_t)(flags | MSG_FLAG_SEQ) << endl;
+    
+    if( flags & MSG_FLAG_SEQ )
+    {
+	d_dbg << ANSI_YELLOW << "packet is sequenced" << endl;
+	// We are not interested in the sequence number, it has been checked
+	// elsewhere
+	(void) rpcs->get_uint32_t();
+    }
+///FIXME we need to recycle the stream in all cases !
+    try
+    {
+	switch( type )
+	{
+	    case MSG_CODE_SSLSTARTUP: // This is known but shouldnt have made it
+		// until here since the connection itself should handle it normally
+		{
+		    rc->send_simple_error(MSG_REASON_INTERNAL, chan);
+		    rc->recycle_stream(rpcs);
+		}
+		return;
+	    case MSG_CODE_ERROR:
+		{
+		    d_dbg << ANSI_RED << "An error of a remote system was detected" << ANSI_NORMAL << endl;
+
+		    handle_error( rc, rpcs->get_uint32_t(), chan );
+//		    d_dbg << ANSI_RED << "Remote Host had an internal error, disconnecting" << ANSI_NORMAL << endl;
+		    rc->recycle_stream(rpcs);
+//		    rc->disconnect();
+		}
+		return;
+	    case MSG_CODE_ASS_RETURN:
+		{
+		    d_dbg << ANSI_BLUE << "A system returned a positive association return" << ANSI_NORMAL << endl;
+		    finish_associate( rc, rpcs, chan );
+		}
+		break;
+	    case MSG_CODE_CALL_OBJECT:
+		{
+		    d_dbg << ANSI_RED << "This message took the wrong way, its a bug" << ANSI_NORMAL << endl;
+		    BUG("MSG_CODE_CALL_OBJECT is not handled here anymore");
+		    /*
+		    hostid_t caller = rpcs->get_uid();
+		    oid_t object = rpcs->get_uid();
+		    uint32_t func = rpcs->get_uint32_t();
+		    uint32_t fver = rpcs->get_uint32_t();
+		    do_call(object, caller, rc, chan, func, fver );
+		    */
+		}
+		break;
+	    case MSG_CODE_ASSOCIATE:
+		{
+		    d_dbg << ANSI_VIOLET << "Someone would like to associate to us" << ANSI_NORMAL << endl;
+		    hostid_t caller = rpcs->get_uid();
+		    oid_t object = rpcs->get_uid();
+		    cid_t cid = rpcs->get<cid_t>();
+		    d_dbg << "No we have all the data of who it is" << endl;
+		    d_dbg << "Data amount left: " << rpcs->data() << endl;
+		    if( rpcs->data() )
+		    {
+			// trailing data
+			THROW(iwruntime_error,("Trailing data in packet"));
+		    }
+		    object_associate(rc,chan,caller,object,cid);
+		}
+		return;
+	    default: ///@todo TODO dont throw, rather send an error msg back later.
+		d_err << "Got unknown Message Code: 0x" << hex << (unsigned)type << endl;
+		UNIMPLEMENTED
+	}
+    } 
+    catch( const buffer_error& be ) //most probably due to invalid stream size
+    {
+	THROW( protocol_error,("Buffer Error",chan,MSG_REASON_BUFFER,&be));
+    }
+}
+
+
+} // namespace net
+} // namespace iwear
+/**
+ * $Log$
+ * Revision 1.18  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.17  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.16  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.15  2005/09/06 11:35:49  plasmahh
+ * added functions
+ *
+ * Revision 1.14  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.13  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.12  2005/06/24 13:16:38  plasmahh
+ * Debian stinkt bis hierher
+ *
+ * Revision 1.11  2005/05/01 12:54:46  plasmahh
+ * fixed doxygen bailout
+ *
+ * Revision 1.10  2005/04/25 21:36:39  plasmahh
+ * mag ich mag ich nicht
+ *
+ * Revision 1.9  2005/04/21 19:41:57  plasmahh
+ * after work sync
+ *
+ * Revision 1.8  2005/04/20 14:30:48  plasmahh
+ *  new files
+ */
Index: /tags/help/iwearrpc/src/xdrstream.cpp
===================================================================
--- /tags/help/iwearrpc/src/xdrstream.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/xdrstream.cpp (revision 2256)
@@ -0,0 +1,495 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <xdrstream.h>
+#include <iwear/debugstream.h>
+#include <iwremote/protocol.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+XDRStream::XDRStream( size_t sz )/*{{{*/
+    : bufsize(sz),
+    bufpos(0),
+    maxbufpos(0)
+{
+    buffer = buf_ = new char[sz];
+//    cout << "ALLOCATED XDR BUFFER AT " << (void*)buf_ << endl;
+}/*}}}*/
+
+XDRStream::XDRStream( char * buf, size_t sz )/*{{{*/
+    : buf_(NULL),buffer(buf),bufsize(sz),bufpos(0), maxbufpos(0)
+{
+    cout << "CREATED XDR BUFFER FROM " << (void*)buf_ << endl;
+}/*}}}*/
+
+XDRStream::~XDRStream( )/*{{{*/
+{
+    delete[] buf_;
+}/*}}}*/
+
+/// sz is octets needed
+#define CHECK_BUFFER(sz)	\
+if( (bufpos + sz) > bufsize )   \
+{\
+    d_dbg << "Wanted " << sz << " got " << bufsize  << " at " << bufpos << endl; \
+    size_t rn = bufpos + sz; \
+    rn *= 3;  \
+    rn /= 2;  \
+    d_dbg << "Auto-Resizing to " << rn << endl; \
+    resize(rn); \
+}
+
+//    THROW(buffer_error,("Buffer too small to put or read data",0));
+
+void XDRStream::put_bool( bool t )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(bool));
+
+    if( t )
+    {
+	buffer[bufpos] = 0xFF;
+    }
+    else
+    {
+	buffer[bufpos] = 0x00;
+    }
+
+    bufpos += sizeof(bool);
+    maxbufpos = max(maxbufpos,bufpos);
+}/*}}}*/
+
+bool XDRStream::get_bool( void )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(bool));
+    bool ret;
+    if( buffer[bufpos] > 0 )
+    {
+	ret = true;
+    }
+    else
+    {
+	ret = false;
+    }
+    bufpos += sizeof(bool);
+    maxbufpos = max(maxbufpos,bufpos);
+    return ret;
+}/*}}}*/
+
+void XDRStream::put_int8_t( int8_t t )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(int8_t));
+    int8_t* ptr = reinterpret_cast<int8_t*>(buffer + bufpos);
+
+    *ptr = t;
+    bufpos += sizeof(int8_t);
+    maxbufpos = max(maxbufpos,bufpos);
+}/*}}}*/
+
+int8_t XDRStream::get_int8_t( void )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(int8_t));
+    int8_t* ptr = reinterpret_cast<int8_t*>(buffer + bufpos);
+
+    int8_t ret = *ptr;
+    bufpos += sizeof(int8_t);
+
+    maxbufpos = max(maxbufpos,bufpos);
+    return ret;
+}/*}}}*/
+
+void XDRStream::put_uint8_t( uint8_t t )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(uint8_t));
+    uint8_t* ptr = reinterpret_cast<uint8_t*>(buffer + bufpos);
+
+    *ptr = t;
+    bufpos += sizeof(uint8_t);
+    maxbufpos = max(maxbufpos,bufpos);
+}/*}}}*/
+
+uint8_t XDRStream::get_uint8_t( void )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(uint8_t));
+    uint8_t* ptr = reinterpret_cast<uint8_t*>(buffer + bufpos);
+
+    uint8_t ret = *ptr;
+    bufpos += sizeof(uint8_t);
+
+    maxbufpos = max(maxbufpos,bufpos);
+    return ret;
+}/*}}}*/
+
+void XDRStream::put_int16_t( int16_t t )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(int16_t));
+    int16_t* ptr = reinterpret_cast<int16_t*>(buffer + bufpos);
+
+    *ptr = htons(t);
+    bufpos += sizeof(int16_t);
+    maxbufpos = max(maxbufpos,bufpos);
+}/*}}}*/
+
+int16_t XDRStream::get_int16_t( void )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(int16_t));
+    int16_t* ptr = reinterpret_cast<int16_t*>(buffer + bufpos);
+
+    int16_t ret = ntohs(*ptr);
+    bufpos += sizeof(int16_t);
+
+    maxbufpos = max(maxbufpos,bufpos);
+    return ret;
+}/*}}}*/
+
+void XDRStream::put_uint16_t( uint16_t t )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(uint16_t));
+    uint16_t* ptr = reinterpret_cast<uint16_t*>(buffer + bufpos);
+
+    *ptr = htons(t);
+    bufpos += sizeof(uint16_t);
+    maxbufpos = max(maxbufpos,bufpos);
+}/*}}}*/
+
+uint16_t XDRStream::get_uint16_t( void )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(uint16_t));
+    uint16_t* ptr = reinterpret_cast<uint16_t*>(buffer + bufpos);
+
+    uint16_t ret = ntohs(*ptr);
+    bufpos += sizeof(uint16_t);
+
+    maxbufpos = max(maxbufpos,bufpos);
+    return ret;
+}/*}}}*/
+
+void XDRStream::put_uint32_t( uint32_t t )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(uint32_t));
+    uint32_t* ptr = reinterpret_cast<uint32_t*>(buffer + bufpos);
+
+    *ptr = htonl(t);
+    bufpos += sizeof(uint32_t);
+    maxbufpos = max(maxbufpos,bufpos);
+}/*}}}*/
+
+uint32_t XDRStream::get_uint32_t( void )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(uint32_t));
+    uint32_t* ptr = reinterpret_cast<uint32_t*>(buffer + bufpos);
+
+    uint32_t ret = ntohl(*ptr);
+    bufpos += sizeof(uint32_t);
+
+    maxbufpos = max(maxbufpos,bufpos);
+    return ret;
+}/*}}}*/
+
+void XDRStream::put_int32_t( int32_t t )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(int32_t));
+    int32_t* ptr = reinterpret_cast<int32_t*>(buffer + bufpos);
+
+    *ptr = htonl(t);
+    bufpos += sizeof(int32_t);
+    maxbufpos = max(maxbufpos,bufpos);
+}/*}}}*/
+
+int32_t XDRStream::get_int32_t( void )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(int32_t));
+    int32_t* ptr = reinterpret_cast<int32_t*>(buffer + bufpos);
+
+    int32_t ret = ntohl(*ptr);
+    bufpos += sizeof(int32_t);
+
+    maxbufpos = max(maxbufpos,bufpos);
+    return ret;
+}/*}}}*/
+
+void XDRStream::put_int64_t( int64_t t )/*{{{*/
+{
+    put_uint64_t(t);
+}/*}}}*/
+
+int64_t XDRStream::get_int64_t( void )/*{{{*/
+{
+    return get_uint64_t();
+}/*}}}*/
+
+void XDRStream::put_uint64_t( uint64_t t )/*{{{*/
+{
+    // Send as two integers
+    CHECK_BUFFER(sizeof(uint64_t));
+    uint32_t a = (t>>32);
+    uint32_t b = (t & 0xFFFFFFFF);
+
+    put_uint32_t(a);
+    put_uint32_t(b);
+}/*}}}*/
+
+uint64_t XDRStream::get_uint64_t( void )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(uint64_t));
+    uint64_t a = get_uint32_t();
+    uint64_t b = get_uint32_t();
+
+    uint64_t ret = (a<<32) + b;
+    return ret;
+}/*}}}*/
+
+string XDRStream::get_string( void )/*{{{*/
+{
+    CHECK_BUFFER(sizeof(uint32_t));
+    uint32_t str_len = get_uint32_t();
+    if( str_len > MAX_IWRPC_STRING )
+    {
+	//TODO better exception with more info
+	THROW(iwruntime_error,("Incoming string exceeds MAX_IWRPC_STRING"));
+    }
+    // A byte is a character is an octet...
+    CHECK_BUFFER(str_len);
+    string ret(buffer + bufpos,str_len); // just copy
+    bufpos += str_len;
+    maxbufpos = max(maxbufpos,bufpos);
+
+    return ret;
+}/*}}}*/
+
+void XDRStream::put_string(const string& str)/*{{{*/
+{
+    CHECK_BUFFER(sizeof(uint32_t) + str.length() );
+    put_uint32_t(str.length());
+    memcpy(buffer + bufpos,str.data(),str.length());
+    bufpos += str.length();
+    maxbufpos = max(maxbufpos,bufpos);
+}/*}}}*/
+
+void XDRStream::put_uid( const uid& id )/*{{{*/
+{
+    CHECK_BUFFER(2 * sizeof(uint64_t) );
+    uint64_t p0 = id.get_the_id(0);
+    uint64_t p1 = id.get_the_id(1);
+    put_uint64_t(p0);
+    put_uint64_t(p1);
+}/*}}}*/
+
+uid XDRStream::get_uid(void)/*{{{*/
+{
+    CHECK_BUFFER(2 * sizeof(uint64_t) );
+    uint64_t p0;
+    uint64_t p1;
+    p0 = get_uint64_t();
+    p1 = get_uint64_t();
+
+    return uid(p0,p1);
+}/*}}}*/
+
+#define FLOAT_MAX_LONG 2147483647.0f
+#define DOUBLE_MAX_LLONG 9223372036854775807.0
+void XDRStream::put_float( float t )/*{{{*/
+{
+    int e;
+    float f = frexpf(t, &e);
+    float u;
+    if( f > 0 )
+    {
+	u = (1.0f/f) - 1.0f; // result is from 1-2 so 0-1
+    }
+    else
+    {
+	u = (1.0f/f) + 1.0f; // result is from 1-2 so 0-1
+    }
+    int32_t mrd = lroundf(u * FLOAT_MAX_LONG);
+    put_int32_t(mrd);
+    put_int8_t(e);
+}/*}}}*/
+
+void XDRStream::put_double( double t )/*{{{*/
+{
+    int e;
+    double f = frexp(t, &e);
+    double u;
+    if( f > 0 )
+    {
+	u = (1.0/f) - 1.0; // result is from 1-2 so 0-1 now
+    }
+    else
+    {
+	u = (1.0/f) + 1.0; // result is from 1-2 so 0-1
+    }
+    cout << "Need to put " << u << endl;
+
+    int64_t mrd = llround(u * (double)DOUBLE_MAX_LLONG);
+    cout << "put as int " << mrd << endl;
+    put_int64_t(mrd);
+    put_int16_t(e);
+}/*}}}*/
+
+float XDRStream::get_float( void )/*{{{*/
+{
+    ///FIXME possibly its easier to multiply and divide by 2 instead of inverting ?
+    int32_t mant = get_int32_t();
+    int8_t e = get_int8_t();
+
+    float un = (float)mant / FLOAT_MAX_LONG;
+
+    float fn;
+    if( un > 0 )
+    {
+	fn = 1.0f/(un + 1.0f);
+    }
+    else
+    {
+	fn = 1.0f/(un - 1.0f);
+    }
+    float ret = ldexpf(fn, e);
+    return ret;
+}/*}}}*/
+
+double XDRStream::get_double( void )/*{{{*/
+{
+    int64_t mant = get_int64_t();
+    int16_t e = get_int16_t();
+
+    double un = (double)mant / (double)DOUBLE_MAX_LLONG;
+
+    double fn;
+    if( un > 0 )
+    {
+	fn = 1.0/(un + 1.0);
+    }
+    else
+    {
+	fn = 1.0/(un - 1.0);
+    }
+    double ret = ldexp(fn, e);
+    return ret;
+}/*}}}*/
+
+std::pair<char *, uint32_t> XDRStream::get_buffer( void )/*{{{*/
+{
+    return make_pair(buffer,maxbufpos);
+}/*}}}*/
+
+std::pair<const char *, uint32_t> XDRStream::get_buffer( void ) const/*{{{*/
+{
+    return make_pair(buffer,maxbufpos);
+}/*}}}*/
+
+size_t XDRStream::max_size( void )/*{{{*/
+{
+    return bufsize;
+}/*}}}*/
+
+void XDRStream::resize( size_t ns )/*{{{*/
+{
+    if( ns > bufsize )
+    {
+	char* newbuf = new char[ns];
+	memcpy(newbuf,buffer,bufsize);
+
+	delete[] buf_;
+
+	buffer = buf_ = newbuf;
+	bufsize = ns;
+    }
+    else
+    {
+	d_dbg << "We dont make an XDRStream smaller" << endl;
+    }
+}/*}}}*/
+
+void XDRStream::replace_buffer( char * nb, uint32_t bs )/*{{{*/
+{
+    delete[] buf_;
+    buffer = buf_ = nb; // This is now our buffer and we will delete it
+    bufsize = bs;
+    ///XXX FIXME Handle bufpos, maxbufpos
+}/*}}}*/
+
+void XDRStream::set_buffer( char * nb, uint32_t bs)/*{{{*/
+{
+    delete[] buf_;
+    buf_ = 0; // The buffer does not belong to us
+    bufsize = bs;
+    buffer = nb;
+    ///XXX FIXME Handle bufpos, maxbufpos
+}/*}}}*/
+
+void XDRStream::replace( RPCStream& rp )/*{{{*/
+{
+    // if this throws because the provided stream isnt an xdr, we let it
+    // propagate up
+    XDRStream& xr = dynamic_cast<XDRStream&>(rp);
+    delete[] buf_;
+
+    buffer = buf_ = xr.buf_;
+    xr.buf_ = 0;
+    bufsize = xr.bufsize;
+    xr.bufsize = 0;
+    ///XXX FIXME Handle bufpos, maxbufpos
+}/*}}}*/
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.11  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.10  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.9  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.8  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.7  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.6  2005/04/25 07:49:34  plasmahh
+ * gradegebogen, alle module müssen das gleiche haben
+ *
+ * Revision 1.5  2005/04/21 19:41:57  plasmahh
+ * after work sync
+ *
+ * Revision 1.4  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.3  2005/01/21 23:34:31  plasmahh
+ * more ideas and stuff
+ *
+ * Revision 1.2  2004/12/01 00:31:13  plasmahh
+ * mehr doku
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/src/remoteconnection.cpp
===================================================================
--- /tags/help/iwearrpc/src/remoteconnection.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/remoteconnection.cpp (revision 2256)
@@ -0,0 +1,276 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <remoteconnection.h>
+#include <rpcstream.h>
+#include <iwear/debugstream.h>
+#include <iwear/uid.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+RemoteConnection::RemoteConnection( CallProvider* cp, bool ms, float oto)
+    : operation_timeout(oto),
+    cond(Mutex),
+    master_side(ms),
+    is_sequenced(false),
+    prov(cp),
+    act_seq(0),
+    refcount(0)
+{
+}
+
+RemoteConnection::~RemoteConnection()
+{
+}
+
+RemoteObject* RemoteConnection::get_object( chanid_t chan )
+{
+    // get the object on the channel
+    map<chanid_t, RemoteObject*>::const_iterator fi(object_on_channel.find(chan));
+
+    if( fi == object_on_channel.end())
+    {
+	return 0;
+    }
+    else
+    {
+	return fi->second;
+    }
+}
+
+void RemoteConnection::allocate_channel( RemoteObject* ro, chanid_t ch )
+{
+    d_dbg << "really Allocating channel: " << ch << endl;
+    d_dbg << preallocated_channels.size() << " channels left" << endl;
+    if( !preallocated_channels.erase(ch) )
+    {
+	THROW(protocol_error,("Strange, this chanid was not preallocated",ch,MSG_REASON_NOCHAN,0));
+    }
+    object_on_channel.insert(make_pair(ch,ro));
+    active_channels.insert(ch);
+    d_dbg << preallocated_channels.size() << " channels left" << endl;
+    // woop, from here on... were associated :)
+}
+
+void RemoteConnection::preallocate_channel( uint16_t chan )
+{
+    d_dbg << "Preallocating channel: " << chan << endl;
+
+    d_dbg << iwexception::backtrace() << endl;
+    /// XXX is it really good to send msgs on this channel, since it seems to
+    //be occupied by another virtual connection ? At least if the host sends
+    //some invalid chan it either thinks it can use this channel, so it will
+    //await it there, or its totally messed up in case we cant really help with
+    //anything
+    if( master_side )
+    {
+	THROW(protocol_error,("Noone should give us a channel if were master",chan,MSG_REASON_NOCHAN,0));
+    }
+
+    ThreadLocker tl(Mutex);
+    map<chanid_t, RemoteObject*>::iterator mi(object_on_channel.begin());
+
+    d_dbg << ANSI_VIOLET << "preallocating channel " << chan << ANSI_NORMAL << endl;
+    d_dbg << "Already have objects on: ";
+    for(; mi != object_on_channel.end(); ++mi )
+    {
+	d_dbg << mi->first << ",";
+    }
+    d_dbg << endl;
+    // look if this is an already allocated channel
+    if( object_on_channel.find(chan) != object_on_channel.end() )
+    {
+	THROW(protocol_error,("There is already an object associated on this connection",chan,MSG_REASON_NOCHAN,0));
+    }
+
+    set<chanid_t>::iterator pi(preallocated_channels.begin());
+
+    d_dbg << ANSI_VIOLET << "preallocating channel " << chan << ANSI_NORMAL << endl;
+    d_dbg << "Already have objects on: ";
+    for(; pi != preallocated_channels.end(); ++pi )
+    {
+	d_dbg << *pi << ",";
+    }
+    d_dbg << endl;
+
+    // look if its already preallocated
+    if( preallocated_channels.find(chan) != preallocated_channels.end() )
+    {
+	THROW(protocol_error,("This channel is already preallocated",chan,MSG_REASON_NOCHAN,0));
+    }
+    //mk, so we can use this channel, remove it from freelist 
+    freed_channels.erase(chan);
+
+    // its now preallocated
+    d_dbg << ANSI_RED << chan << " is now preallocated" << ANSI_NORMAL << endl;
+    preallocated_channels.insert(chan);
+}
+
+uint16_t RemoteConnection::preallocate_channel( void )
+{
+    d_dbg << ANSI_VIOLET << "preallocating own side channel" << ANSI_NORMAL << endl;
+    if( ! master_side )
+    {
+	return 0;
+    }
+    /// @todo TODO FIXME find a better algorithm for channel allocation which
+    /// an attacker cannot exploit (this can be, allocating and deallocating
+    /// two channels will result in 1-2 channels allocated but channel
+    /// increasing always, need something that keeps either channel low or knows
+    /// about reallocation of them)
+    ThreadLocker tl(Mutex);
+
+    uint16_t new_chan = 0;
+    if( freed_channels.size() )
+    {
+	set<uint16_t>::iterator nci(freed_channels.begin());
+	new_chan = (*nci);
+	freed_channels.erase(nci);
+	return new_chan;
+    }
+    // Ok, we do not have any freed channel.. so probably the best way at this
+    // point is to look for the max of preallocated and allocated
+    uint16_t px = 0;
+    if( preallocated_channels.size() )
+    {
+	set<uint16_t>::iterator pi(preallocated_channels.end());
+	--pi;
+	px = *pi;
+    }
+
+    uint16_t ox = 0;
+    if( object_on_channel.size() )
+    {
+	map<uint16_t, RemoteObject*>::iterator oi(object_on_channel.end());
+	--oi;
+	ox = oi->first;
+    }
+
+    new_chan = max(px,ox);
+    ++new_chan;
+
+    d_dbg << ANSI_RED << new_chan << " is now preallocated" << ANSI_NORMAL << endl;
+    preallocated_channels.insert(new_chan);
+    return new_chan;
+}
+
+int RemoteConnection::wait_for_channel( uint16_t chan )
+{
+    ///XXX in the loop, maybe we should look for data too, like asking the
+    //callprovider to check all its connections (which would of course include
+    //us too)
+
+    while( stream_queue.get<1>().find(chan) == stream_queue.get<1>().end() )
+    {
+	usleep(1000);
+	if( ! is_connected() ) return -1;
+	///FIXME: do it in a better way with the conditional stuff and waiting channel maps
+    }
+    ///FIXME this would wait forever if nothing arrives on the channel
+}
+
+void RemoteConnection::got_sequence( uint32_t sq )
+{
+    UNIMPLEMENTED    
+}
+
+uint32_t RemoteConnection::next_sequence( void )
+{
+    if( act_seq == 0 ) return 0;
+
+    return act_seq;
+}
+
+void RemoteConnection::handle_error( const protocol_error& p )
+{
+    d_dbg << "Ok, protocol error, sending back response:" << endl;
+    d_dbg << p << endl;
+    // silently send back a negative response...
+    if( p.error() )
+    {
+	send_simple_error( p.error(), p.channel() );
+    }
+    else
+    {
+	send_simple_error( MSG_REASON_DEFECT, p.channel() );
+    }
+}
+
+void RemoteConnection::send_simple_error( uint32_t rsn, chanid_t chan )
+{
+    d_dbg << "Sending error: " << rsn << " on chan " << chan << endl;
+    uint32_t ns = next_sequence();
+    uint32_t sz = 4/*packet_length*/ + 4/*flags,types,channel*/ + 4/*error reason*/;
+
+    if( ns )
+    {
+	sz += 4; // a sequence is needed
+    }
+
+    RPCStream* rpcs = get_stream( sz );
+
+    rpcs->put_uint32_t(sz);
+    rpcs->put_uint8_t(get_actual_flags());
+    rpcs->put_uint8_t(MSG_CODE_ERROR);
+    rpcs->put_uint16_t(chan); 
+
+    if( ns )
+    {
+	d_dbg << ANSI_RED << "WARNING Sending Error with sequence number" << ANSI_NORMAL << endl;
+	rpcs->put_uint32_t(ns);
+    }
+    rpcs->put_uint32_t(rsn);
+
+    send_rpcpacket(rpcs);
+}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.7  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.6  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.5  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.4  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.3  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.2  2005/08/10 21:58:16  plasmahh
+ * changed all include guards to include directory to not clash with other libraries... work to do :)
+ *
+ * Revision 1.1  2005/06/30 18:37:30  plasmahh
+ * sync
+ *
+ */
Index: /tags/help/iwearrpc/src/testclient.cpp
===================================================================
--- /tags/help/iwearrpc/src/testclient.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/testclient.cpp (revision 2256)
@@ -0,0 +1,137 @@
+
+extern "C" {
+#include <rpc/xdr.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+}
+
+#include <iwremote/callmanager.h>
+// keep this the first include please
+#include <iwear/debugstream.h>
+#include <iwear/configuration.h>
+#include <iwremote/rootartano.h>
+#include <iwear/shmemory.h>
+#include <iwear/servicemanager.h>
+#include <iwear/sysvsemaphore.h>
+#include <iwear/tcpconnection.h>
+#include <iwear/utility.h>
+#include <iwremote/class.h>
+#include <iwremote/cppoutput.h>
+#include <iwremote/declaration.h>
+#include <iwremote/enum.h>
+#include <iwremote/function.h>
+#include <iwremote/idloutput.h>
+#include <iwremote/namespace.h>
+#include <iwremote/translationunit.h>
+#include <iwremote/xdrstream.h>
+#include <iwremote/socketprovider.h>
+#include <iwremote/socketconnectiondescriptor.h>
+#include <../testclient.h>
+#include <iwear/buildphase.h>
+
+#include <iostream>
+using namespace std;
+using namespace iwear;
+using namespace iwear::net;
+using namespace iwear::sensor;
+
+int main ( void )
+{
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+    d_err.set_debuglevel(nonsens);
+    BuildPhase::build_phase = 1;
+//    enable_verbose_crash();
+
+    try
+    {
+	Configuration conf;
+	ServiceManager SM(conf);
+	RootArtano RA(&SM);
+
+	CallManager& cman = RA.get_callmanager();
+
+	SocketProvider sprov(&cman);
+
+	cman.add_callprovider(&sprov);
+
+	RA.Init();
+//	cout << cm->get_name() << " : " << cm->get_uid() << endl;
+//	cout << "Ok, we are running and hopefully ready to accept connections..." << endl;
+
+	cout << "Our (and thus debug targets) uid:" << cman.get_uid() << endl;
+	oid_t tr("testuid");
+	RemoteDescriptor rd;
+	rd.hostid = cman.get_uid();
+	rd.objectid = tr;
+	TCPConnection* tcp = new TCPConnection;
+	intrusive_ptr<SocketRemoteConnection> src = SocketRemoteConnection::create(tcp,&sprov,true,0.2,0.2,0.2);
+
+	src->_debug_set_ip("localhost");
+	src->_debug_set_port(4242);
+	sprov._debug_add_connection(src.get());
+
+	SocketConnectionDescriptor cd(src);
+	HostConnector hc(&(cman.get_uid()),&cd);
+	cout << "HostConnector Host id: " << cman.get_uid() << endl;
+	
+	RA._debug_add_uid_rmt(&tr,&rd);
+	cman._debug_add_host_list(&(cman.get_uid()),hc);
+	try
+	{
+	    RemoteDataSensor* rds = dynamic_cast<RemoteDataSensor*>(RA.resolve(uid("testuid")));
+	    d_dbg << ANSI_RED << "*********+*********************************************" << ANSI_NORMAL << endl;
+	    d_dbg << "Remote Data Sensor : " << (void*) rds << endl;
+	    d_dbg << "Calling trigger(0.5) (watch server)" << endl;
+	    rds->trigger(0.5);
+	    d_dbg << "Called trigger." << endl;
+	    d_dbg << ANSI_RED << "*********+*********************************************" << ANSI_NORMAL << endl;
+	}
+	catch( const exception& e )
+	{
+	    cout << "could not reolve:" << endl;
+	    cout << e << endl;
+	}
+
+	usleep(1000000000);
+	cout << errno << endl;
+	usleep(1000000000);
+	cout << errno << endl;
+	usleep(1000000000);
+	cout << errno << endl;
+	usleep(1000000000);
+	cout << errno << endl;
+	usleep(1000000000);
+	cout << errno << endl;
+    }
+    catch( const exception& e )
+    {
+	cout << "Catched Exception:" << endl;
+	cout << e << endl;
+	usleep(1000000000);
+    }
+
+    /*
+    delete new SysVSemaphore(1,2,3);
+
+    SysVSemaphore sem(1,0,1);
+    cout << "SEM VALUE " << sem.Value() << endl;
+    errno = 0;
+    cout << "RET " << sem.Post() << flush; perror(" " );
+    cout << "SEM VALUE " << sem.Value() << endl;
+    errno = 0;
+    cout << "RET " << sem.Post() << flush; perror(" " );
+    cout << "SEM VALUE " << sem.Value() << endl;
+    errno = 0;
+    cout << "RET " << sem.Wait() << flush; perror(" " );
+    cout << "SEM VALUE " << sem.Value() << endl;
+
+    usleep(1000000000);
+    usleep(1000000000);
+    usleep(1000000000);
+    usleep(1000000000);
+*/
+}
Index: /tags/help/iwearrpc/src/test.cpp
===================================================================
--- /tags/help/iwearrpc/src/test.cpp (revision 2229)
+++ /tags/help/iwearrpc/src/test.cpp (revision 2229)
@@ -0,0 +1,111 @@
+
+extern "C" {
+#include <rpc/xdr.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+}
+
+#include <iwremote/declaration.h>
+#include <iwremote/class.h>
+#include <iwremote/enum.h>
+#include <iwremote/function.h>
+#include <iwremote/namespace.h>
+#include <iwremote/translationunit.h>
+#include <iwear/debugstream.h>
+#include <iwear/utility.h>
+#include <iwremote/idloutput.h>
+#include <iwremote/xdrstream.h>
+#include <iwear/tcpconnection.h>
+#include <iwremote/cppoutput.h>
+
+#include <iostream>
+using namespace std;
+using namespace iwear;
+using namespace iwear::net;
+
+
+int main ( void )
+{
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+    d_err.set_debuglevel(nonsens);
+    enable_verbose_crash();
+
+    TranslationUnit TU;
+    Namespace* nsu = new Namespace("iwear");
+    Namespace* ns = new Namespace("sensor");
+    nsu->add_item(*ns);
+    TU.add_namespace(*nsu);
+
+    Enum* en = new Enum("power_state");
+    en->add_enumdef(EnumDef("off",false,0));
+    en->add_enumdef(EnumDef("on",false,1));
+    ns->add_item(*en);
+
+    Class* cl = new Class("RemoteDataSensor");
+    ns->add_item(*cl);
+    Declaration* dec1 = new Declaration( new Type("uint32_t",false), "test",true);
+    dec1->prot = protected_t;
+    Declaration* dec2 = new Declaration( new Type("double",false), "_M_data",false);
+    dec2->prot = protected_t;
+    cl->add_item(*dec1);
+    cl->add_item(*dec2);
+
+    FunctionArgument fnret1( new Type("void",false), in_t, "" );
+    Function* fn1 = new Function( fnret1, "trigger", false,false,false,0,"");
+
+    fn1->add_argument(FunctionArgument( new Type("double",false), in_t, "arg1" ));
+    cl->add_item(*fn1);
+
+    Class* scl = new Class("ExtendedRemoteDataSensor");
+    scl->add_subclass(SubClass(public_d, cl));
+    ns->add_item(*scl);
+    Declaration* ndec = new Declaration(new Type("double",false), "_X_data", false);
+    scl->add_item(*ndec);
+
+    Function* fn = new Function( FunctionArgument(new Type("double",false), inout_t, "" ),"get_value",false,false,false,0,"");
+
+//    fn->add_argument(FunctionArgument("double", "r", inout_t, true));
+
+    Function* frn = new Function(fnret1,"set_value",false,false,false,0,"");
+//    frn->return_type = FunctionArgument("double", "", inout_t, true);
+    frn->add_argument(FunctionArgument(new Type("double",true), inout_t, "r"));
+    frn->add_argument(FunctionArgument(new Type("double",true), in_t, "ru"));
+
+    scl->add_item(*fn);
+    scl->add_item(*frn);
+
+    Class* rtb = new Class("RemoteTestBase");
+    rtb->version_id = 0x01010000;
+    ns->add_item(*rtb);
+
+    Function* ftn1 = new Function( FunctionArgument(new Type("double",true), inout_t, ""),
+	    "get_data",false,false,false,0x01000000,"get_data_old");
+
+    Function* ftn2 = new Function( FunctionArgument(new Type("double",true), inout_t, ""),
+	    "get_data",false,false,false,0x01010000,"");
+
+    Function* ftn3 = new Function( FunctionArgument(new Type("double",true) , inout_t, ""),
+	    "get_datatime",false,false,false,0,"");
+
+    rtb->add_item(*ftn1);
+    rtb->add_item(*ftn2);
+    rtb->add_item(*ftn3);
+
+
+    Class* rtc = new Class("RemoteTestCached");
+    rtc->add_subclass(SubClass(public_d, rtb));
+    ns->add_item(*rtc);
+
+    Function* rtf = new Function( FunctionArgument(new Type("double",true), inout_t, ""),
+	    "get_data",true,false,false,0,"");
+
+    rtc->add_item(*rtf);
+
+//    IDLOutput idl;
+//    idl.output_tu(TU);
+    CppOutput cpp("test");
+    cpp.output_tu(TU);
+
+    return 0;
+}
Index: /tags/help/iwearrpc/src/remoteobject.cpp
===================================================================
--- /tags/help/iwearrpc/src/remoteobject.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/remoteobject.cpp (revision 2256)
@@ -0,0 +1,78 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <remoteobject.h>
+#include <iwear/uid.h>
+#include <iwremote/remotecaller.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+RemoteObject::RemoteObject( void )
+    : call_timeout(15)
+{
+}
+
+RemoteObject::~RemoteObject( void )
+{
+}
+
+RPCStream* RemoteObject::do_call( const hostid_t hid, RPCStream* rpcs, RemoteConnectionPtr rcon,
+             chanid_t chan, uint32_t func, uint32_t fver )
+{
+    //FIXME call some per-object security measurements !
+    //something like about_to_call_XXXX with hostid as parameter and remotecaller set ?
+
+    ThreadLocker tl(Mutex,call_timeout);
+    RemoteCaller rc;
+    rc.rmc = rcon.get();
+    //FIXME the pass_reason should either be set or replaced by a better mechanism
+    cd.rmt.rmcl = &rc;
+    //XXX if at any time we need to enable recursion, we need here to save the
+    //old callprovider and replace it with the new one.
+    cd.channel = chan;
+
+    RPCStream* ret = _resolve_call(func,fver,rpcs);
+
+    cd.channel = 0;
+    cd.rmt.rmcl = 0;
+    return ret;
+}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.3  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.2  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.1  2005/09/13 23:24:22  plasmahh
+ * hope Im in sync now
+ *
+ */
Index: /tags/help/iwearrpc/src/socketremoteconnection.cpp
===================================================================
--- /tags/help/iwearrpc/src/socketremoteconnection.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/socketremoteconnection.cpp (revision 2256)
@@ -0,0 +1,362 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <socketremoteconnection.h>
+#include <iwear/debugstream.h>
+#include <iwear/ipconnection.h>
+#include <xdrstream.h>
+#include <callprovider.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+boost::intrusive_ptr<SocketRemoteConnection>
+SocketRemoteConnection::create( IPConnection* ipc, CallProvider* cp, bool ms, float oto,float bto,float iot )
+{
+    return boost::intrusive_ptr<SocketRemoteConnection>(new SocketRemoteConnection(ipc,cp,ms,oto,bto,iot));
+}
+
+SocketRemoteConnection::SocketRemoteConnection( IPConnection* ipc, CallProvider* cp, bool ms, float oto,float bto,float iot )
+    : RemoteConnection( cp, ms, oto ),
+    scon(ipc),
+    io_timeout(iot),
+    buffer_timeout(bto),
+    port(0),
+    buffer(0)
+{
+    port = ipc->get_remote_port();
+    ip = ipc->get_remote_ip();
+}
+
+SocketRemoteConnection::~SocketRemoteConnection()
+{
+    try
+    {
+	scon->disconnect();
+	prov->disconnected(this);
+    }
+    catch(...)
+    {
+	/// Ignore all errors, we will delete anyways
+    }
+    delete scon;
+    delete buffer;
+}
+
+void SocketRemoteConnection::send_rpcpacket( const RPCStream* spc )/*{{{*/
+{
+    if( ! scon )
+    {
+	THROW(iwruntime_error,("Dont have an active connection"));
+    }
+
+    if( ! scon->is_connected() )
+    {
+	scon->reconnect();
+	if( ! scon->is_connected() )
+	{
+	    THROW(iwruntime_error,("We were not able to reconnect the connection"));
+	}
+    }
+
+    const char* dat = spc->get_buffer().first;
+    uint32_t sz = spc->get_buffer().second;
+
+    int bt = scon->send(dat,sz,0.01); //TODO need to get the timeout from somewhere else
+    if( bt != sz )
+    {
+	//TODO yeah look how we can send the rest if we did send a bit
+	UNIMPLEMENTED
+    }
+    if( is_sequenced )
+    {
+	act_seq += bt; // Advance the sequence nr.
+    }
+}/*}}}*/
+
+void SocketRemoteConnection::disconnect( void )
+{
+    scon->disconnect();
+    prov->disconnected(this);
+}
+
+bool SocketRemoteConnection::receive_rpcpacket( RPCStream& spc, uint16_t channel )
+{
+    d_dbg << "The queue size:" << stream_queue.size() << endl;
+
+    stream_container::nth_index_iterator<1>::type cit(stream_queue.get<1>().find(channel));
+    if( cit != stream_queue.get<1>().end() )
+    {
+	// XXX make this queueing fairer
+	// found a stream in the cache for the channel, return this instead
+
+	RPCStream* r = cit->second;
+	stream_queue.get<1>().erase(cit);
+	spc.replace(*r);
+	return true;
+    }
+    // first of all, look in our msg_queue if there is some...
+    if( !scon )
+    {
+	throw runtime_error("No Active Connection");
+    }
+
+    //FIXME although it is really unlikely it can be possible that the next
+    //part of the packet will arrive after this
+    uint32_t packet_length;
+    int bt = scon->read(&packet_length, 4,io_timeout);
+
+    if( bt != 4 )
+    {
+	if( bt == 0 )
+	{
+	    d_dbg << "Initial read is 0, assuming nothing yet on connection..." << endl;
+	    d_dbg << "thats strange since now we should not even try to read" << endl;
+	    return false;
+	}
+	//FIXME make the way of the connections in error cases clearer, so they
+	//can be easily removed off the socketset
+	d_dbg << "packet too short, wrong protocol ? (read only " << bt << " bytes )" << endl;
+	THROW(protocol_error,("Packet too short",0,0,0));
+    }
+    packet_length = ntohl(packet_length); // First protocol field 
+    uint32_t packet_rest = packet_length - 4;
+
+    d_dbg << "Packet says its length is " << packet_length << endl;
+    d_dbg << "Allocating space..." << endl;
+
+#define MAX_SOCKET_BUFFER 16384 ///@todo TODO this must be configurable !
+    if( packet_length > MAX_SOCKET_BUFFER )
+    {
+	d_dbg << "Wow this packet is too long" << endl;
+	THROW(protocol_error,("Packet is too long (?)", 0,MSG_REASON_BUFFER,0));
+    }
+    if( packet_length <= (4+4) ) // header minimum is 64Bit (without sequence nr) and we need data
+    {
+	d_dbg << "Wow this packet is too short" << endl;
+	THROW(protocol_error,("Packet is too short (?)", 0,0,0));
+    }
+
+    char* buffa = new char[packet_rest];
+
+    uint32_t rd = scon->read(buffa,packet_rest,io_timeout);
+
+    d_dbg << "Read " << rd << " bytes into the stream" << endl;
+
+    if( packet_rest != rd )
+    {
+	d_dbg << "Packet size mismatch... if its too low, maybe data is missing..." << endl;
+	d_dbg << "Wanted " << packet_rest << " got " << rd << endl;
+	THROW(iwruntime_error,("Packet size mismatch"));
+    }
+
+    //TODO check if the rest can be done in a base function
+    XDRStream tmpxdr( buffa, packet_rest );
+
+    uint8_t packet_flags = tmpxdr.get<uint8_t>();
+    uint8_t packet_type = tmpxdr.get<uint8_t>();
+    chanid_t ci = tmpxdr.get<chanid_t>();
+
+
+
+    d_dbg << "got a msg from channel : " << ci << " with flags " << (uint32_t)packet_flags << " of type " << (uint32_t)packet_type << endl;
+    d_dbg << "and someone wanted from channel:" << channel << endl;
+
+
+    if( !flags_valid(packet_flags) )
+    {
+	d_dbg << "Flag combination not valid" << endl;
+	send_simple_error(MSG_REASON_DEFECT,0);
+	return false;
+    }
+
+    // TODO at this stage decode gzip and or ssl
+    // then we set the ssl/gzip and sequence needed flags from the received
+    // packet
+    actual_flags = packet_flags;
+
+    //TODO verify sequenced packet status
+    if( has_sequence(packet_flags) )
+    {
+	d_dbg << "The message says it has a sequence id" << endl;
+	uint32_t seqid = tmpxdr.get<uint32_t>();
+	got_sequence(seqid);
+    }
+
+    if( ci != channel )
+    {
+
+	d_dbg << ANSI_GREEN << "Channel parameter (wanted to read for):" << channel << endl;
+	d_dbg << "Data arrived at channel:" << ci << ANSI_NORMAL << endl;
+	// look if the channel we received for is active... XXX verify again
+	if( object_on_channel.find(ci) != object_on_channel.end() )
+	{
+	    d_dbg << "The channel belongs to a object-active channel, sort it in" << endl;
+	}
+	else if( active_channels.find(ci) != active_channels.end() )
+	{
+	    d_dbg << "The channel is an otherwise active one" << endl;
+	}
+	else
+	{
+	    d_dbg << "This channel could not be found" << endl;
+
+	    // The channel is not known here
+	    if( master_side &&  ( preallocated_channels.find(ci) == preallocated_channels.end() ) )
+	    {
+		d_dbg << "Ok, the data was not requested but belongs to a preallocated channel, sort it in" << endl;
+		// Were on master, and so we assing all channels, and if this
+		// is not assigned...
+		d_dbg << "ERROR" << endl;
+		send_simple_error(MSG_REASON_NOCHAN,ci);
+		return false;
+	    }
+	    else // Means were not the master side or the channel was preallocated already.
+	    {
+		// The other side has given us a new channel for this packet,
+		// sort it into the queue and mark it as preallocated
+		d_dbg << ANSI_RED << ci << " is now (again) preallocated" << ANSI_NORMAL << endl;
+		preallocated_channels.insert(ci);// even if it was preallocated
+		// before, it does not hurt if we add it again.
+
+		XDRStream* sx = new XDRStream(0);
+		sx->replace_buffer(buffa,packet_rest);
+		prov->insert_system(sx,this);
+	
+		return false;
+	    }
+	}
+	d_dbg << "Looks like someone says we know this channel..." << endl;
+	// its not the channel requested, save it internally and look if we can
+	// get recursively another
+	XDRStream* sx = new XDRStream(0);
+	sx->replace_buffer(buffa,packet_rest);
+	stream_queue.push_back(make_pair(ci,sx));
+	d_dbg << "Inserted packet into queue for further processing of the channel that wants it" << endl;
+
+	///XXX what if really busy on other channels ?
+	return receive_rpcpacket(spc,channel);
+    }
+    else
+    {
+	spc.replace_buffer(buffa, packet_rest );
+	return true;
+    }
+    return false;
+}
+
+void SocketRemoteConnection::recycle_stream( RPCStream* rpcs )
+{
+    // assuming its a XDRStream we dont need anything else
+    delete rpcs;
+}
+
+bool SocketRemoteConnection::has_sslkey( void ) const
+{
+    UNIMPLEMENTED
+}
+
+bool SocketRemoteConnection::get_sslkey( void ) const
+{
+    UNIMPLEMENTED
+}
+
+bool SocketRemoteConnection::is_connected( void ) const
+{
+    return (scon && scon->is_connected() );
+}
+
+bool SocketRemoteConnection::reconnect( void )
+{
+    // we resolve and reconnect here again because of:
+    // - the IPConnection itself has saved IP, but for DNS load balancing we resolve again
+    if( ! scon )
+    {
+	// FIXME
+	// We need to get a new connection to the ip, but what kind of
+	// connection ?
+    }
+    else
+    {
+	if( scon->is_connected() )
+	{
+	    scon->disconnect();
+	    prov->disconnected(this);
+	}
+	try
+	{
+	    ///XXX Put this information into a class and save this as
+	    //connectiondescriptor
+	    scon->connect(ip,port,io_timeout);
+	}
+	catch( const socket_error& se )
+	{
+	    d_dbg << "Within reconnect() : " << endl;
+	    d_dbg << se << endl;
+	    return false;
+	}
+    }
+
+    if(scon)
+    {
+	prov->connected(this);
+    }
+    return true;
+}
+
+void SocketRemoteConnection::set_connection_policy( void )
+{
+    UNIMPLEMENTED
+}
+
+XDRStream* SocketRemoteConnection::get_stream( uint32_t est )
+{
+    return new XDRStream(est);
+}
+
+} // net
+} // iwear
+/**
+ * $Log$
+ * Revision 1.6  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.5  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.4  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.3  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.2  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.1  2005/06/30 18:37:30  plasmahh
+ * sync
+ *
+ */
Index: /tags/help/iwearrpc/src/rpctest.cpp
===================================================================
--- /tags/help/iwearrpc/src/rpctest.cpp (revision 2215)
+++ /tags/help/iwearrpc/src/rpctest.cpp (revision 2215)
@@ -0,0 +1,113 @@
+
+extern "C" {
+#include <rpc/xdr.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+}
+
+#include <iwear/debugstream.h>
+#include <iwear/configuration.h>
+#include <iwremote/rootartano.h>
+#include <iwear/shmemory.h>
+#include <iwear/servicemanager.h>
+#include <iwear/sysvsemaphore.h>
+#include <iwear/tcpconnection.h>
+#include <iwear/utility.h>
+#include <iwremote/callmanager.h>
+#include <iwremote/class.h>
+#include <iwremote/cppoutput.h>
+#include <iwremote/declaration.h>
+#include <iwremote/enum.h>
+#include <iwremote/function.h>
+#include <iwremote/idloutput.h>
+#include <iwremote/namespace.h>
+#include <iwremote/translationunit.h>
+#include <iwremote/xdrstream.h>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/random_number_generator.hpp>
+#include <boost/random/mersenne_twister.hpp>
+
+#include <iostream>
+#include <iomanip>
+using namespace std;
+using namespace iwear;
+using namespace iwear::net;
+
+
+
+int main ( void )
+{
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+    d_err.set_debuglevel(nonsens);
+//    enable_verbose_crash();
+
+    Configuration conf;
+    ServiceManager SM(conf);
+    RootArtano RA(&SM);
+
+    try
+    {
+	RA.Init();
+//	cout << cm->get_name() << " : " << cm->get_uid() << endl;
+    }
+    catch( const sys_error& s )
+    {
+	cout << "Catched Exception of type " << current_exception_name() << endl;
+	cout << "Reason : " << s.what() << endl;
+	cout << "Errno  : " << s.strerror() << endl;
+    }
+    catch( const exception& e )
+    {
+	cout << "Catched Exception of type " << current_exception_name() << endl;
+	cout << "Reason : " << e.what() << endl;
+    }
+
+        boost::mt19937 rng(time(0));
+	//boost::uniform_real<float> tu(-numeric_limits<float>::max(), numeric_limits<float>::max() );
+	        boost::uniform_real<float> tu(-1.0f,1.0f);
+	boost::variate_generator<boost::mt19937&, boost::uniform_real<float> >
+	    die(rng, tu);
+
+    XDRStream xdr(50);
+
+    for( int i = 0; i < 500; ++i )
+    {
+	double tp = die();
+	cout << "put_double(" << tp << ")" << endl;
+	xdr.reset();
+	xdr.put_double(tp);
+	xdr.reset();
+	double g = xdr.get_double();
+	cout << setprecision(60);
+	cout << "get_double() = " << g << endl;
+	cout << "diff = " << (tp-g) << endl;
+    }
+
+    exit(0);
+//    RA.resolve(uid("TEST"));
+//    usleep(1000000000);
+    /*
+    delete new SysVSemaphore(1,2,3);
+
+    SysVSemaphore sem(1,0,1);
+    cout << "SEM VALUE " << sem.Value() << endl;
+    errno = 0;
+    cout << "RET " << sem.Post() << flush; perror(" " );
+    cout << "SEM VALUE " << sem.Value() << endl;
+    errno = 0;
+    cout << "RET " << sem.Post() << flush; perror(" " );
+    cout << "SEM VALUE " << sem.Value() << endl;
+    errno = 0;
+    cout << "RET " << sem.Wait() << flush; perror(" " );
+    cout << "SEM VALUE " << sem.Value() << endl;
+
+    usleep(1000000000);
+    usleep(1000000000);
+    usleep(1000000000);
+    usleep(1000000000);
+*/
+}
Index: /tags/help/iwearrpc/src/function.cpp
===================================================================
--- /tags/help/iwearrpc/src/function.cpp (revision 2229)
+++ /tags/help/iwearrpc/src/function.cpp (revision 2229)
@@ -0,0 +1,248 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <function.h>
+#include <iwear/crc.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+string Function::get_crcstring( void )
+{
+    if ( crcs.length() ) return crcs; // so we dont need to re-calculate
+    list<FunctionArgument>::iterator fit(arguments.begin());
+
+    crcs = id; // the function name
+
+    crcs += return_type.get_crcstring();
+
+    for ( ; fit != arguments.end(); ++fit )
+    {
+	crcs += fit->get_crcstring();
+    }
+    return crcs;
+}
+
+void Function::generate_crcids(const string& cs)
+{
+    CRC32 crc;
+    crc.process_bytes(cs.c_str(),cs.length());
+    string ccs = get_crcstring();
+    crc.process_bytes(ccs.c_str(),ccs.length());
+    crcid = crc.checksum();
+}
+
+string Function::get_outsize( void )
+{
+    // size for all what should go back out, so first is return
+    list<FunctionArgument>::iterator fit(arguments.begin());
+
+    string ret;
+    ret += return_type.type->get_static_size();
+    if(ret.length()) ret = "+" + ret;
+
+    for ( ; fit != arguments.end(); ++fit )
+    {
+	if( fit->mytype == out_t || fit->mytype == inout_t )
+	{
+	    ret += "+" + fit->type->get_dynamic_size( fit->id );
+	}
+    }
+    return ret;
+}
+
+string Function::get_insize( void )
+{ 
+    // size for all what should go back out, so first is return
+    list<FunctionArgument>::iterator fit(arguments.begin());
+
+    string ret;
+
+    for ( ; fit != arguments.end(); ++fit )
+    {
+	if( fit->mytype == in_t || fit->mytype == inout_t )
+	{
+	    ret += fit->type->get_dynamic_size( fit->id );
+	}
+    }
+    return ret;
+}
+
+string FunctionArgument::get_crcstring( void )
+{
+    ContainerType* ct = dynamic_cast<ContainerType*>(type);
+    string ret;
+
+    if(ct)
+    {
+	ret += "container_of";
+	ret += ct->id->id;
+    }
+    else
+    {
+	ret += type->id;
+    }
+
+    if( type->reference )
+    {
+	ret += "reference_of";
+    }
+    
+    // in,out etc.
+    switch( mytype )
+    {
+	case in_t:
+	    ret += "in_t";
+	    break;
+	case out_t:
+	    ret += "out_t";
+	    break;
+	case inout_t:
+	    ret += "inout_t";
+	    break;
+	default:
+	    THROW(iwruntime_error,("internal error"));
+    }
+    return ret;
+}
+
+bool Type::builtin( void )
+{
+    if( id == "void" ) return true;
+
+    return get_static_size().length();
+}
+
+string Type::get_dynamic_size( const string& var )
+{
+    string ret;
+    ret = get_static_size();
+    if( ret.length() ) return ret;
+
+    if( id == "string" )
+    {
+	// reserve 4 for the length descriptor
+	return "(4 + " + var + ".size())";
+    }
+    return "(" + var + ".get_minsize())";
+}
+
+string Type::get_static_size( void )
+{
+    if( reference ) return "16"; // A reference is implicitly a uid
+
+    if( id == "uint8_t" || id == "int8_t" || id == "bool" )
+    {
+	return "1";
+    }
+    else if( id == "uint16_t" || id == "int16_t" || id == "chanid_t" )
+    {
+	return "2";
+    }
+    else if( id == "uint32_t" || id == "int32_t" || id == "cid_t" )
+    {
+	return "4";
+    }
+    else if( id == "uint64_t" || id == "int64_t" )
+    {
+	return "8";
+    }
+    else if( id == "float" )
+    {
+	return "(4+1)";
+    }
+    else if( id == "double" )
+    {
+	return "(8+2)";
+    }
+    else if ( id == "uid" || id == "oid_t" || id == "hostid_t" )
+    {
+	return "16";
+    }
+    return "";
+}
+
+string ContainerType::get_static_size( )
+{
+    return "";
+}
+
+string ContainerType::get_dynamic_size( const string& var )
+{
+    if( id->builtin() )
+    {
+	string ret;
+	ret += "sz += (" + var + ".size() * ";
+	ret += id->get_static_size() + ")";
+	return ret;
+    }
+    else
+    {
+	string cont;
+	cont += container;
+	cont += "<";
+	cont += id->id;
+	cont += ">";
+	string ret;
+
+	ret += "{";
+	ret += cont;
+	ret += "::iterator ctit(" + var + ".begin());";
+	ret += "for(; ctit != " + var + ".end(); ++ctit )";
+	ret += "{";
+	ret += "sz += ";
+	if( id->id == "string" )
+	{
+	    ret += "ctit->size();";
+	}
+	else
+	{
+	    ret += "ctit->min_size();";
+	}
+	ret += "}";
+
+	ret += "}";
+	return ret;
+    }
+}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.4  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/src/declaration.cpp
===================================================================
--- /tags/help/iwearrpc/src/declaration.cpp (revision 2229)
+++ /tags/help/iwearrpc/src/declaration.cpp (revision 2229)
@@ -0,0 +1,68 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <declaration.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+string Declaration::get_crcstring( void )
+{
+    crcs += type->id; // the actual type
+    if(readonly)
+    {
+	crcs += "readonly";
+    }
+    return crcs;
+}
+
+void Declaration::generate_crcids( const string& )
+{
+    // whoops ?
+}
+
+string Declaration::get_own_size( void )
+{
+    return type->get_static_size();
+}
+
+    }
+}
+/**
+ * $Log$
+ * Revision 1.4  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/src/chainsecurityprovider.cpp
===================================================================
--- /tags/help/iwearrpc/src/chainsecurityprovider.cpp (revision 2252)
+++ /tags/help/iwearrpc/src/chainsecurityprovider.cpp (revision 2252)
@@ -0,0 +1,68 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <chainsecurityprovider.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+ChainSecurityProvider::ChainSecurityProvider()
+{
+}
+
+ChainSecurityProvider::~ChainSecurityProvider()
+{
+}
+
+bool ChainSecurityProvider::check_connection( RemoteConnectionPtr rcon )
+{
+    return true;
+    UNIMPLEMENTED
+}
+
+bool ChainSecurityProvider::check_host( RemoteConnectionPtr rcon, const hostid_t& hid )
+{
+    return true;
+    UNIMPLEMENTED
+}
+
+bool ChainSecurityProvider::check_object( RemoteConnectionPtr rcon, const hostid_t& hid, const oid_t& oid )
+{
+    return true;
+    UNIMPLEMENTED
+}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.2  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ */
Index: /tags/help/iwearrpc/src/nullstream.cpp
===================================================================
--- /tags/help/iwearrpc/src/nullstream.cpp (revision 1143)
+++ /tags/help/iwearrpc/src/nullstream.cpp (revision 1143)
@@ -0,0 +1,46 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <iwremote/nullstream.h>
+#include <iwear/debugstream.h>
+#include <iwear/i18n.h>
+
+namespace iwear
+{
+    namespace net
+    {
+NULLStream::NULLStream( size_t ned )
+{
+    d_warn << i18n::trans("Warning, request for NULL RPC stream, system should shortcut call !") << endl;
+}
+
+} // namespace iwear
+} // namespace net
+
+/**
+ * $Log$
+ * Revision 1.1  2005/01/21 23:35:45  plasmahh
+ * some more stuff
+ *
+ */
Index: /tags/help/iwearrpc/src/callprovider.cpp
===================================================================
--- /tags/help/iwearrpc/src/callprovider.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/callprovider.cpp (revision 2256)
@@ -0,0 +1,192 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <callprovider.h>
+#include <remoteobject.h>
+#include <iwear/scopetracer.h>
+#include <rpcstream.h>
+#include <callmanager.h>
+
+namespace iwear
+{
+    namespace net
+    {
+CallProvider::CallProvider( CallManager* cm )
+    :cman(cm)
+{
+}
+
+CallProvider::~CallProvider()
+{
+}
+
+void CallProvider::do_call( const oid_t& oid, const hostid_t& hid, RemoteConnectionPtr rcon,
+	RPCStream* rpcs, chanid_t chan, uint32_t func, uint32_t fver )
+{
+    // get the object on the channel
+    RemoteObject* fo = rcon->get_object(chan);
+    if( ! fo )
+    {
+	THROW(protocol_error,("This chan is not on this connection",chan,MSG_REASON_NOCHAN,0));
+    }
+
+    //FIXME here we need to add some security checks ! (call the callmanager for that)
+
+    d_dbg << "Wanted uid of client:\"" << oid << "\"" << endl;
+    d_dbg << "This channel uid obj:\"" << fo->get_uid() << "\"" << endl;
+    d_dbg << "The callers host was:\"" << hid << "\"" << endl;
+    if( fo->get_uid() != oid )
+    {
+	THROW(protocol_error,("This oid_t is not active on this channel",chan,MSG_REASON_NOUID,0));
+    }
+
+    ///XXX Maybe this call must be scheduled in a thread to avoid hanging the
+    /// whole system if the object hangs ?
+    RPCStream* ret = fo->do_call( hid, rpcs, rcon, chan, func, fver );
+    if ( ! ret ) // assume it was an oneway call
+    {
+	// dont do anything else yet
+    }
+    else
+    {
+	cman->finish_packet(ret);
+	rcon->send_rpcpacket(ret);
+    }
+    rcon->recycle_stream(rpcs); //XXX check if this is really the right place to do
+}
+
+void CallProvider::interpret_channelstream( chanid_t chan, RPCStream* rpcs, RemoteConnectionPtr rc )
+{
+    ScopeTracer st(__FFL__);
+
+    rpcs->reset();
+    uint8_t flags = rpcs->get_uint8_t();
+    uint8_t type = rpcs->get_uint8_t();
+    uint16_t chn = rpcs->get_uint16_t();
+
+    if( chn != chan ) BUG("Passed wrong channel, maybe it was in the wrong queue");
+
+    if( flags & MSG_FLAG_SEQ )
+    {
+        d_dbg << ANSI_YELLOW << "packet is sequenced" << endl;
+        // We are not interested in the sequence number, it has been checked
+        // elsewhere
+        (void) rpcs->get_uint32_t();
+    }
+
+    try
+    {
+	switch(type)
+	{
+	    case MSG_CODE_CALL_OBJECT:
+		{
+		hostid_t caller = rpcs->get_uid();
+		oid_t object = rpcs->get_uid();
+		uint32_t func = rpcs->get_uint32_t();
+		uint32_t fver = rpcs->get_uint32_t();
+		do_call(object, caller, rc, rpcs, chan, func, fver );
+		}
+		break;
+	    case MSG_CODE_CALL_RETURN:
+	    case MSG_CODE_CALL_ERROR:
+	    case MSG_CODE_ERROR:
+		///FIXME this is inefficient and could lead to packets beeing
+		//endlessly queued. lookup the waiting channel stuff and
+		//putback the packet there into special operations.
+		d_dbg << "Ok, these messages are to be interpreted by someone else, reappend it to the queue" << endl;
+		d_dbg << "CHN = " << chn << endl;
+		rc->stream_queue.push_back(make_pair(chn,rpcs));
+		pthread_yield();
+		break;
+	    default:
+		d_dbg << "The received MSG CODE was: " << (unsigned)type << endl;
+		THROW( protocol_error,("This MSG_CODE is not handled here",chan,MSG_REASON_INTERNAL,0));
+		break;
+	}
+    }
+    catch( const buffer_error& be ) //most probably due to invalid stream size
+    {
+	THROW( protocol_error,("Buffer Error",chan,MSG_REASON_BUFFER,&be));
+    }
+}
+
+void CallProvider::insert_system( RPCStream* rpcs, RemoteConnectionPtr rcon )
+{
+    msgq.push(make_pair(rpcs,rcon));
+}
+
+void CallProvider::check_channels( void )
+{
+    set<RemoteConnectionPtr >::iterator ri(remote_connections.begin());
+    for(; ri != remote_connections.end(); ++ri )
+    {
+	// FIXME Lock the remote connection here !!
+
+	///XXX Data hide
+
+	stream_container::size_type qs = (*ri)->stream_queue.size();
+	if( qs )
+	{
+	    //XXX do we want to empty first all of this queue or round-robin
+	    //check the others ? 
+
+	    stream_container::size_type qi = 0;
+	    stream_container::size_type qx = (qs/2) + 1;
+
+	    for(; qi < qx; ++qi )
+	    {
+		pair<chanid_t, RPCStream*> qp = (*ri)->stream_queue.front();
+		(*ri)->stream_queue.pop_front();
+		try
+		{
+		    interpret_channelstream( qp.first, qp.second, *ri );
+		}
+		catch( const protocol_error& pe )
+		{
+		    (*ri)->handle_error(pe);
+		}
+
+	    }
+	}
+    }
+
+}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.4  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.3  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.2  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.1  2005/08/23 23:37:21  plasmahh
+ * all the new files that are needed
+ *
+ */
Index: /tags/help/iwearrpc/src/rootartano.cpp
===================================================================
--- /tags/help/iwearrpc/src/rootartano.cpp (revision 2256)
+++ /tags/help/iwearrpc/src/rootartano.cpp (revision 2256)
@@ -0,0 +1,537 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <rootartano.h>
+#include <callmanager.h>
+#include <iwear/debugstream.h>
+#include <protocol.h>
+#include <iwremote/remoteobject.h>
+#include <iwremote/remoteconnection.h>
+#include <iwremote/rpcstream.h>
+#include <iwear/scopetracer.h>
+
+namespace iwear
+{
+    namespace net
+    {
+
+map<uint32_t,RemoteObject*(*)()>* RootArtano::cid_inst = NULL;
+multimap<cid_t,RemoteObject*(*)()>* RootArtano::server_inst = 0;
+
+RootArtano::RootArtano( ServiceManager* sm )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+
+    cman = new CallManager(sm,this);
+    if( cid_inst == NULL )
+    {
+	d_warn << "No classes registered yet, you probably need to load some as plugins..." << endl;
+    }
+}/*}}}*/
+
+RootArtano::~RootArtano( )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    delete cman;
+}/*}}}*/
+
+CallManager& RootArtano::get_callmanager( void )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    if( cman )
+    {
+	return *cman;
+    }
+    else
+    {
+	throw nullptr_error("Dont have a CallManager");
+    }
+}/*}}}*/
+
+const CallManager& RootArtano::get_callmanager( void ) const/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    if( cman )
+    {
+	return *cman;
+    }
+    else
+    {
+	throw nullptr_error("Dont have a CallManager");
+    }
+}/*}}}*/
+/*
+ * TODO
+ * Ok, we have the class providers to provide us information of how we can
+ * create the objects. If the class providers function pointer is 0 then this
+ * means that this class does not allow itself to be generated on request.
+ *
+ * Another thing we should worry about is, when we have created such an object,
+ * can we call on it multiple times ? when do we destroy it ?
+ */
+void RootArtano::remove_client(cid_t cid )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    if( ! cid_inst )
+    {
+	//Keep the printf here, cout isnt usable in static initialization/destruction !
+	printf("Removing class instatiotor whithout map, something is seriously wrong!\n");
+	abort();
+    }
+
+    try
+    {
+	cid_inst->erase(cid);
+    }
+    catch( const exception& e )
+    {
+	printf("Error at static destruction of RootArtano class provide information: %s\n",e.what());
+	abort();
+    }
+}/*}}}*/
+
+void RootArtano::provide_client(cid_t cid, RemoteObject* (*fp)() )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    if ( ! cid_inst )
+    {
+	cid_inst = new map<cid_t ,RemoteObject*(*)()>;
+    }
+
+    try
+    {
+	cid_inst->insert(make_pair(cid,fp));
+    }
+    catch(const exception& e )
+    {
+	// its not perfectly safe to use printf at this point but I think safer
+	// than using cout in a static context...
+	printf("Error at static initialization of RootArtano: %s\n",e.what());
+	abort();
+    }
+}/*}}}*/
+
+void RootArtano::provide_server( vector<cid_t>& cids, RemoteObject* fp() )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    if( ! server_inst )
+    {
+	server_inst = new multimap<cid_t,RemoteObject*(*)()>;
+    }
+
+    vector<cid_t>::iterator vi(cids.begin());
+
+    try
+    {
+	for(; vi != cids.end(); ++vi )
+	{
+	    server_inst->insert(make_pair(*vi,fp));
+	}
+    }
+    catch(const exception& e )
+    {
+	// its not perfectly safe to use printf at this point but I think safer
+	// than using cout in a static context...
+	printf("Error at static initialization of RootArtano: %s\n",e.what());
+	abort();
+    }
+}/*}}}*/
+
+void RootArtano::remove_server( RemoteObject* fp() )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    if( ! server_inst )
+    {
+	//Keep the printf here, cout isnt usable in static initialization/destruction !
+	printf("Removing class instatiotor whithout map, something is seriously wrong!\n");
+	abort();
+    }
+
+    try
+    {
+	multimap<cid_t,RemoteObject*(*)()>::iterator mi(server_inst->begin());
+	for(; mi != server_inst->end();)
+	{
+	    if( mi->second == fp )
+	    {
+		server_inst->erase(++mi);
+		continue;
+	    }
+	    ++mi;
+	}
+    }
+    catch( const exception& e )
+    {
+	printf("Error at static destruction of RootArtano class provide information: %s\n",e.what());
+	abort();
+    }
+}/*}}}*/
+
+void RootArtano::Init( void )
+{
+    ScopeTracer st(__FFL__);
+    cman->Init();
+    cman->Start();
+}
+/*
+RemoteObject* RootArtano::resolve( const uid& id, uint32_t classid )
+{
+}
+*/
+
+RemoteObject* RootArtano::associate_on_connection( RemoteConnectionPtr rc, const oid_t& id, resolve_behaviour rb )/*{{{*/
+{
+    ScopeTracer st(__FFL__);
+    d_dbg << ANSI_BLUE << "Starting to associate a connection with an object" << ANSI_NORMAL << endl;
+    if( ! rc->is_connected() )
+    {
+	// Let the exception that this will throw propagate up to the user
+	rc->reconnect();
+    }
+
+    RemoteConnectionPtr rcon = rc.get();
+
+    // We need to pass a plain pointer, since this pointer is passed as
+    // reference, and thus might as well be changed. This should not harm the
+    // reference counting mechanism, since we still have a refcounted
+    // intrusive_ptr rc which is not yet destroyed.
+    // The only thing we assume here is that within the
+    // send_associate_request() there is no such pointer saved anywhere for
+    // later use, only as a intrusive_ptr it would be allowed.
+    uint16_t chan = cman->send_associate_request( rcon, id, 0 ); 
+    // We dont actually care bout the crcid here (until we get it of course)
+    // Ok, and now wait for the reply...
+d_dbg << __FFL__  << endl;
+//    int ret = rcon->wait_for_channel(chan); //TODO what about the timeout, where does it come from ?
+    //ok, here it looks like we got a reply on the channel
+
+ //   if( ret <  0 )
+    {
+	// then an error occured
+	
+    }
+d_dbg << __FFL__  << endl;
+
+    // if the association was succesfully... 
+    RPCStream& ar = cman->get_association_return( rcon, id, chan );
+    // TODO if something fails here, we have a protocol error, maybe we should
+    // catch exceptions and throw a more generic one (maybe a chained one)
+
+d_dbg << __FFL__  << endl;
+    ar.reset();
+    (void) ar.get_uint8_t();
+    uint8_t flags = ar.get_uint8_t();
+    (void) ar.get_uint16_t();
+
+    if( rcon->has_sequence(flags) )
+    {
+	(void)ar.get_uint32_t();
+    }
+
+    hostid_t h = ar.get_uid();
+    oid_t o = ar.get_uid();
+
+    d_dbg << "Host ID: " << h << endl;
+    d_dbg << "Object ID: " << o << endl;
+
+    // The number of cid_t entries
+    uint16_t cid_s = ar.get_uint16_t();
+    vector<cid_t> cids;
+    cids.resize(cid_s);
+    d_dbg << "This class implements " << cid_s << " cids" << endl;
+    RemoteObject* ro = 0;
+    for(uint16_t i = 0; i < cid_s; ++i )
+    {
+	cid_t nc = ar.get<cid_t>();
+	cids[i] = nc;
+	cout << "Remote implements: 0x" << hex << nc << endl;
+	if( ! ro )
+	{
+	    ro = create_instance(nc);
+	}
+    }
+    rcon->allocate_channel(ro,chan);
+
+    //mk, until here we know nearly everything about the object, just the data
+    //is left...
+    ro->fill_from_serverstream(&ar);
+    ro->set_uid(o);
+    ro->cd.rmt.rmcn = rc.get();
+    ro->cman = cman;
+    ro->channel_id = chan;
+
+
+    
+
+
+    // XXX set callprovider
+    // XXX set rpc side
+
+    return ro;
+}/*}}}*/
+
+RemoteObject* RootArtano::create_instance( cid_t cid )
+{
+    ScopeTracer st(__FFL__);
+    if( ! cid_inst )
+    {
+	THROW(nullptr_error,("no client instances available"));
+    }
+
+    map<cid_t,RemoteObject*(*)()>::iterator ci(cid_inst->find(cid));
+    if( ci != cid_inst->end() )
+    {
+	return ci->second();
+    }
+    else
+    {
+	return 0;
+    }
+}
+
+RemoteObject* RootArtano::resolve( const uid& id, resolve_behaviour rb, search_behaviour sb )
+{
+    ScopeTracer st(__FFL__);
+    ThreadLocker tl(Mutex);
+    d_dbg << ANSI_BLUE << "RootArtano starting resolve process for uid " << ANSI_VIOLET << id << ANSI_NORMAL << endl;
+
+    // First Lookup our cache if we already know about this RemoteObject
+    map<const uid*,RemoteObject*,deref_less<const uid*> >::iterator ri(rmos.find(&id));
+
+    if( ri != rmos.end() )
+    {
+	d_dbg << ANSI_GREEN << "Found a RemoteObject with the specified uid in local cache" << ANSI_NORMAL << endl;
+	// Since we are the only one that should be allowed to change the
+	// reference value we are locked here and simply do it
+	ri->second->referrer++;
+	return ri->second;
+    }
+    d_dbg << ANSI_YELLOW << "Did not found RemoteObject in local cache, but perhaps we know where it is" << ANSI_NORMAL << endl;
+
+    // Ok, it was not in our "live" object cache, lets ask the callmanager for
+    // RemoteConnections we could associate with.
+    RemoteConnectionPtr rc = cman->get_responsible_connection(id);
+
+    if( rc )
+    {
+	d_dbg << ANSI_GREEN << "Ok, found a responsible connection" << ANSI_NORMAL << endl;
+
+	return associate_on_connection( rc, id, rb );
+    }
+    else
+    {
+	d_dbg << ANSI_YELLOW << "Could not find a responsible connection for uid" << ANSI_NORMAL << endl;
+    }
+
+    // Could not find a cached connection. Now search for the uid if we have a
+    // description of where to connect to to get it...
+
+    map<const oid_t*,RemoteDescriptor*,deref_less<const oid_t*> >::iterator si(uid_rmt.find(&id));
+
+    if( si != uid_rmt.end() )
+    {
+	// Found a remotedescriptor, yeha ! ;)
+d_dbg << ANSI_GREEN << "Found a way to get to this uid (corresponding RemoteDescriptor)" << ANSI_NORMAL << endl;
+d_dbg << ANSI_BLUE << "The host id is:" << si->second->hostid << ANSI_NORMAL << endl;
+	RemoteConnectionPtr rcon = cman->get_connection_to_host( si->second->hostid );
+	if( rcon )
+	{
+	    d_dbg << ANSI_GREEN << "CallManager also knows hot to get there" << endl;
+	    return associate_on_connection(rcon,id,rb);
+	}
+	else
+	{
+	    d_dbg << ANSI_YELLOW << "Sorry, but CallManager does not know how to get to the host" << endl;
+	}
+    }
+    else
+    {
+	d_dbg << ANSI_YELLOW << "Sorry, could not find a RemoteDescriptor for the uid" << ANSI_NORMAL << endl;
+    }
+
+    cman->search_providing_host( id, sb );
+    
+    d_dbg << ANSI_RED << "P2P and Broadcast and Multicast Search currently not implemented" << ANSI_NORMAL << endl;
+
+    // Hm, we dont know where to find the object, issue a search request, wait
+    // a while and look if we know it then
+    return 0;
+}
+
+void RootArtano::recycle( RemoteObject* ro )
+{
+    ScopeTracer st(__FFL__);
+    ThreadLocker tl(Mutex);
+
+    if( ro->cd.myside != rpc_client )
+    {
+	throw runtime_error("Cannot recycle a client side object, the user has to delete it");
+    }
+
+    ro->referrer--;
+
+    if( ro->referrer > 0)
+    {
+	// Simply return its in use at another place
+	return;
+    }
+
+    if( ro->referrer < 0)
+    {
+	throw runtime_error("Negative reference count on RemoteObject, recycled too often ?");
+    }
+
+    if( ro->referrer == 0 )
+    {
+	// Really recycle the object here
+	// - Tell the Server System that you do so
+	// - Tell the connection that we dont need it any more (If we were the
+	//   only user, it will probably terminate)
+	// - delete the object finally...
+
+	RemoteConnectionPtr rc = ro->cd.rmt.rmcn;
+	// We assemble and send the message here since we dont want to
+	// (accidently) have a RemoteObject do it itself
+	send_deassociate( rc, ro );
+
+	delete ro;
+    }
+}
+
+void RootArtano::send_deassociate( RemoteConnectionPtr rc, RemoteObject* ro )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+/*
+    RPCStream& rpcs = cman->get_sysrpcstream( rc, SIZE_HEADER + SIZE_UID + SIZE_UID );
+    // Packet length and Call Sequence ID was already set/reserved
+    rpcs.put_uint32_t(MSG_CODE_DEASSOCIATE);
+    rpcs.put_uid(cman->get_uid()); // The calling host uid
+    rpcs.put_uid(ro->get_uid());
+    rc->send_rpcpacket(rpcs);
+    cman->release_rpcstream(rpcs);
+    */
+}
+
+RPCStream& RootArtano::get_search_packet( const uid& id, uint32_t hopcount )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+    /*
+    RPCStream& rpcs = cman->get_sysrpcstream( 0, 
+	    SIZE_HEADER + SIZE_WORD + SIZE_WORD + SIZE_WORD + SIZE_UID + SIZE_UID );
+
+    rpcs.put_uint32_t(MSG_CODE_SEARCH);
+    rpcs.put_uint32_t(MSG_SEARCH_UID);
+    rpcs.put_uint32_t(hopcount);
+    rpcs.put_uid(cman->get_uid());
+    rpcs.put_uid( id );
+
+    return rpcs;
+    */
+}
+
+RPCStream& RootArtano::get_search_packet( uint32_t crcid, uint32_t hopcount )
+{
+    ScopeTracer st(__FFL__);
+    UNIMPLEMENTED
+    /*
+    RPCStream& rpcs = cman->get_sysrpcstream( 0,
+	    SIZE_HEADER + SIZE_WORD + SIZE_WORD + SIZE_WORD + SIZE_UID + SIZE_WORD );
+
+    rpcs.put_uint32_t(MSG_CODE_SEARCH);
+    rpcs.put_uint32_t(MSG_SEARCH_CID);
+    rpcs.put_uint32_t(hopcount);
+    rpcs.put_uid(cman->get_uid());
+    rpcs.put_uint32_t(crcid);
+
+    return rpcs;
+    */
+}
+
+void RootArtano::register_object( const oid_t& oid, RemoteObject* ro )
+{
+    ScopeTracer st(__FFL__);
+    ///TODO FIXME check if its there first
+    oid_object.insert(make_pair(&oid,ro));
+}
+
+RemoteObject* RootArtano::get_object( const oid_t& oid )
+{
+    ScopeTracer st(__FFL__);
+    cout << "Object requested, searching " << oid_object.size() << " objects" << endl;
+
+    map<const oid_t*, RemoteObject*,deref_less<const oid_t*> >::iterator ofi(oid_object.begin());
+    for(; ofi != oid_object.end(); ++ ofi )
+    {
+	cout << "OID: " << *(ofi->first) << endl;
+    }
+
+    map<const oid_t*, RemoteObject*,deref_less<const oid_t*> >::iterator fi(oid_object.find(&oid));
+
+    if( fi != oid_object.end() )
+    {
+	return fi->second;
+    }
+    else
+    {
+	return 0;
+    }
+}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.11  2005/09/14 15:53:10  plasmahh
+ * first call that works
+ *
+ * Revision 1.10  2005/09/14 00:49:35  plasmahh
+ * fixed hopefully boost multi_index stuff
+ *
+ * Revision 1.9  2005/09/13 23:22:53  plasmahh
+ * ok, does not compile, sorry
+ *
+ * Revision 1.8  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.7  2005/08/23 23:23:04  plasmahh
+ * first association tests worked
+ *
+ * Revision 1.5  2005/04/25 21:36:39  plasmahh
+ * mag ich mag ich nicht
+ *
+ * Revision 1.4  2005/04/25 07:49:34  plasmahh
+ * gradegebogen, alle module müssen das gleiche haben
+ *
+ * Revision 1.3  2005/04/21 19:41:57  plasmahh
+ * after work sync
+ *
+ * Revision 1.2  2005/04/20 18:08:45  plasmahh
+ * har ahr
+ *
+ * Revision 1.1  2005/04/20 14:30:48  plasmahh
+ *  new files
+ *
+ */
Index: /tags/help/iwearrpc/src/idloutput.cpp
===================================================================
--- /tags/help/iwearrpc/src/idloutput.cpp (revision 2229)
+++ /tags/help/iwearrpc/src/idloutput.cpp (revision 2229)
@@ -0,0 +1,314 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <idloutput.h>
+#include <iostream>
+#include <iwear/utility.h>
+using namespace std;
+
+namespace iwear
+{
+    namespace net
+    {
+
+void IDLOutput::output_declaration( Declaration& d, uint32_t indlev )
+{
+//    cout << __FFL__ << endl;
+    string inds = get_inds(indlev);
+    cout << inds;
+    if ( d.readonly )
+    {
+	cout << "readonly ";
+    }
+    cout << d.type << " ";
+    cout << d.id << ";" << endl;
+}
+
+void IDLOutput::output_function( Function & f, uint32_t indlev )
+{
+    string inds = get_inds(indlev);
+
+    cout << inds;
+    if ( f.is_cached )
+    {
+	cout << "cached ";
+    }
+    if ( f.is_oneway )
+    {
+	/// FIXME TODO @todo check for void return here and issue error if not
+	cout << "oneway ";
+    }
+    if ( f.return_type.type )
+    {
+	cout << f.return_type.type;
+    }
+    else
+    {
+	cout << "void";
+    }
+    cout << " " << f.id;
+    if ( f.version_id )
+    {
+	output_version_id(f.version_id);
+    }
+    cout << "( ";
+
+    if ( f.arguments.size() == 0 )
+    {
+	cout << "void";
+    }
+    list<FunctionArgument>& fal = f.arguments;
+    list<FunctionArgument>::iterator it = fal.begin();
+    for( ; it != fal.end(); ++it )
+    {
+	if ( it != fal.begin() )
+	{
+	    cout << ", ";
+	}
+	switch( it->mytype )
+	{
+	    case in_t:
+		cout << "in ";
+		break;
+	    case out_t:
+		cout << "out ";
+		break;
+	    case inout_t:
+		cout << "inout ";
+		break;
+	    default:
+		throw runtime_error("invalid value in switch");
+	}
+	cout << it->type;
+        if ( it->id.length() )
+	{
+	    cout << " " << it->id;
+	}
+    }
+    cout << " )";
+    if ( f.version_id )
+    {
+	/// TODO check here for ??
+	cout << " = " << f.versioncall;
+    }
+    cout << ";";
+    cout << endl;
+}
+
+void IDLOutput::output_enum( Enum& e, uint32_t indlev )
+{
+    string inds = get_inds(indlev);
+    string inds2 = get_inds(indlev+1);
+    
+    cout << inds << "enum " << e.id << endl;
+    cout << inds << "{" << endl;
+    list<EnumDef>& ed = e.get_enumdefs();
+    list<EnumDef>::iterator it = ed.begin();
+    for (; it != ed.end(); ++it )
+    {
+	cout << inds2 << it->id;
+	if ( it->value_set )
+	{
+	    cout << " = ";
+	    cout << it->value;
+	}
+        cout << "," << endl;
+    }
+
+    cout << inds << "};" << endl;
+    cout << endl;
+}
+
+string IDLOutput::get_inds( uint32_t indlev )/*{{{*/
+{
+    string inds;
+    for ( unsigned int i = 0; i < indlev/2; i++ )
+    {
+	inds += "\t";
+    }
+    if ( indlev%2 )
+    {
+	inds += "    ";
+    }   
+    return inds;
+}/*}}}*/
+
+void IDLOutput::output_version_id( uint32_t vid )/*{{{*/
+{
+    uint32_t maj = vid & 0xff000000;
+    uint32_t min = vid & 0x00ff0000;
+    uint32_t rev = vid & 0x0000ff00;
+
+    maj >>= 24;
+    min >>= 16;
+    rev >>=  8;
+
+    cout << "[";
+    if ( rev )
+    {
+	cout << maj << "." << min << "." << rev;
+    }
+    else if ( min || maj)
+    {
+	cout << maj << "." << min;
+    }
+    else
+    {
+	throw runtime_error(string("Called ") + __PRETTY_FUNCTION__ + " with argument 0"); 
+    }
+    cout << "]";
+}/*}}}*/
+
+void IDLOutput::output_class( Class& c, uint32_t indlev )/*{{{*/
+{
+    string inds = get_inds(indlev);
+    cout << inds << "class " << c.id;
+    if ( c.version_id )
+    {
+//	cout << inds;
+	output_version_id(c.version_id);
+    }
+
+    if ( c.subclasses.size() )
+    {
+	cout << " : ";
+	list<SubClass>::iterator it = c.subclasses.begin();
+	for ( ; it != c.subclasses.end(); ++it)
+	{
+	    if ( it != c.subclasses.begin() )
+	    {
+		cout << ", ";
+	    }
+	    switch ( it->d_t )
+	    {
+		case  public_d:
+		    cout << "public ";
+		    break;
+		case  protected_d:
+		    cout << "protected ";
+		    break;
+		case  private_d:
+		    cout << "private ";
+		    break;
+		case  virtual_d:
+		    cout << "virtual ";
+		    break;
+		case  public_virtual_d:
+		    cout << "virtual public";
+		    break;
+		case  protected_virtual_d:
+		    cout << "virtual protected";
+		    break;
+		case  private_virtual_d:
+		    cout << "virtual private";
+		    break;
+		default:
+		    throw runtime_error("Invalid switch case");
+	    }
+	    cout << it->d_class->id;
+	}
+    }
+    cout << endl;
+    cout << inds << "{" << endl;
+    list<ClassItem*>::iterator cit( c.items.begin() );
+    ++indlev;
+    for(; cit != c.items.end(); ++cit)
+    {
+	switch( (*cit)->get_classitem_type() )
+	{
+	    case function_cit:
+		output_function((Function&)**cit,indlev);
+		break;
+	    case declaration_cit:
+		output_declaration((Declaration&)**cit,indlev);
+		break;
+	    case class_cit:
+		output_class((Class&)**cit,indlev);
+		break;
+	    case enum_cit:
+		output_enum((Enum&)**cit,indlev);
+		break;
+	    default:
+		throw runtime_error("ClassItem with wrong item type");
+	}
+    }
+    cout << inds << "};" << endl;
+    cout << endl;
+}/*}}}*/
+
+void IDLOutput::output_tu( TranslationUnit& tu )/*{{{*/
+{
+    list<Namespace*>& tus = tu.get_namespaces();
+    list<Namespace*>::iterator nit( tus.begin() );
+
+    for(; nit != tus.end(); ++nit )
+    {
+	output_namespace(**nit,0);
+    }
+}/*}}}*/
+
+void IDLOutput::output_namespace( Namespace& ns, uint32_t indlev )/*{{{*/
+{
+    cout << "namespace " << ns.id << " { " << endl;
+    list<NamespaceItem*>::iterator nit( ns.items.begin() );
+
+    ++indlev;
+    for(; nit != ns.items.end(); ++nit )
+    {
+	switch( (*nit)->get_namespaceitem_type() )
+	{
+	    case namespace_t:
+		output_namespace((Namespace&)**nit,indlev);
+		break;
+	    case class_t:
+		output_class((Class&)**nit,indlev);
+		break;
+	    case enum_t:
+		output_enum((Enum&)**nit,indlev);
+		break;
+	    default:
+		throw runtime_error("Invalid type for NamespaceItem");
+	}
+    }
+    cout << "}" << endl;
+}/*}}}*/
+
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.4  2005/09/06 11:35:50  plasmahh
+ * added functions
+ *
+ * Revision 1.3  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.2  2004/12/02 22:39:04  plasmahh
+ * first code output generation possible (totally incomplete)
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/src/remotetest.cpp
===================================================================
--- /tags/help/iwearrpc/src/remotetest.cpp (revision 1410)
+++ /tags/help/iwearrpc/src/remotetest.cpp (revision 1410)
@@ -0,0 +1,39 @@
+
+extern "C" {
+#include <rpc/xdr.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+}
+
+#include <iwremote/declaration.h>
+#include <iwremote/class.h>
+#include <iwremote/enum.h>
+#include <iwremote/function.h>
+#include <iwremote/namespace.h>
+#include <iwremote/translationunit.h>
+#include <iwear/debugstream.h>
+#include <iwear/utility.h>
+#include <iwremote/idloutput.h>
+#include <iwremote/xdrstream.h>
+#include <iwear/tcpconnection.h>
+#include <iwremote/cppoutput.h>
+
+//#include "testserverimplementation.h"
+
+#include <iostream>
+using namespace std;
+using namespace iwear;
+using namespace iwear::net;
+using namespace iwear::sensor;
+
+int main ( void )
+{
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+    d_err.set_debuglevel(nonsens);
+    enable_verbose_crash();
+
+//    RemoteTestCached_ServerImplementation rtcs;
+    RemoteDataSensor_ServerImplementation Ti;
+    
+}
Index: /tags/help/iwearrpc/src/namespace.cpp
===================================================================
--- /tags/help/iwearrpc/src/namespace.cpp (revision 1182)
+++ /tags/help/iwearrpc/src/namespace.cpp (revision 1182)
@@ -0,0 +1,57 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <namespace.h>
+namespace iwear
+{
+    namespace net
+    {
+
+void Namespace::add_item( NamespaceItem& ni )
+{
+    items.push_back(&ni);
+}
+
+string Namespace::get_crcstring( void )
+{
+    return id;
+}
+
+}
+}
+/**
+ * $Log$
+ * Revision 1.4  2005/02/17 22:41:07  plasmahh
+ * qeowghg
+ *
+ * Revision 1.3  2004/12/17 09:26:16  plasmahh
+ * kaputt machen fuer weihnachten
+ *
+ * Revision 1.2  2004/12/05 00:25:40  plasmahh
+ * iwremote stuff
+ *
+ * Revision 1.1  2004/11/29 13:21:05  plasmahh
+ * new
+ *
+ */
Index: /tags/help/iwearrpc/src/Makefile
===================================================================
--- /tags/help/iwearrpc/src/Makefile (revision 2257)
+++ /tags/help/iwearrpc/src/Makefile (revision 2257)
@@ -0,0 +1,34 @@
+# Where exactly are we ?
+TOPDIR=..
+
+all: test
+
+include ../Makefile.common
+-include .depend
+
+test: test.o lib
+	@echo $(BLU)[LD]$(NOR) $@
+	@$(CPP) $(CPPFLAGS) $(LIBINCLUDE) $(LIBS) -liwremote -lm test.o -o $@
+
+testserver: testserver.o lib
+	@echo $(BLU)[LD]$(NOR) $@
+	@$(CPP) $(CPPFLAGS) $(LIBINCLUDE) $(LIBS) -liwsens -liwremote  -lm testserver.o ../testserver.o ../testcommon.o -o $@
+testclient: testclient.o lib
+	@echo $(BLU)[LD]$(NOR) $@
+	@$(CPP) $(CPPFLAGS) $(LIBINCLUDE) $(LIBS) -liwremote  -lm testclient.o ../testclient.o ../testcommon.o -o $@
+
+rpctest: rpctest.o lib
+	@echo $(BLU)[LD]$(NOR) $@
+	@$(CPP) $(CPPFLAGS) $(LIBINCLUDE) $(LIBS) -liwremote -lm rpctest.o -o $@
+
+remotetest: remotetest.o lib
+	@echo $(BLU)[LD]$(NOR) $@
+	@$(CPP) $(CPPFLAGS) $(LIBINCLUDE) $(LIBS) -liwremote -lm remotetest.o ../testcommon.o ../testserver.o ../testclient.o -o $@
+
+frag: frag.o lib
+	@echo $(BLU)[LD]$(NOR) $@
+	@$(CPP) $(CPPFLAGS) $(LIBINCLUDE) $(LIBS) -liwear_core -lm frag.o -o $@
+
+poread: poread.o lib
+	@echo $(BLU)[LD]$(NOR) $@
+	@$(CPP) $(CPPFLAGS) $(LIBINCLUDE) $(LIBS) -liwear_core -lm poread.o -o $@
Index: /tags/help/iwearrpc/COPYRIGHT
===================================================================
--- /tags/help/iwearrpc/COPYRIGHT (revision 1057)
+++ /tags/help/iwearrpc/COPYRIGHT (revision 1057)
@@ -0,0 +1,24 @@
+/**
+ * @file
+ * $Id$
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ * This file is part of The iWear Framework.
+ *
+ * The iWear Framework 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.
+ * 
+ * The iWear Framework 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
+ * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
Index: /tags/help/iwearrpc/NOTES
===================================================================
--- /tags/help/iwearrpc/NOTES (revision 2229)
+++ /tags/help/iwearrpc/NOTES (revision 2229)
@@ -0,0 +1,3 @@
+@throw angabe in der doku: Generelle angabe für interne selbstgeworfene
+exceptions. Es kann sein dass z.b. STL iteratoren exceptions werfen, die werden
+damit natürlich nicht aufgeführt.
Index: /tags/help/iwearrpc/functions
===================================================================
--- /tags/help/iwearrpc/functions (revision 2229)
+++ /tags/help/iwearrpc/functions (revision 2229)
@@ -0,0 +1,2179 @@
+#!/bin/bash
+C_TEMPDIR=`mktemp -d /tmp/iwear-configure.XXXXXX`
+
+PQLIBDIRS="/usr/lib/ /usr/lib/pgsql/ /usr/local/pgsql/lib/"
+PQINCDIRS="/usr/include/ /usr/include/pgsql /usr/include/postgresql /usr/local/pgsql/include /usr/include/postgresql/8.0/"
+SSLINCDIRS="/usr/include/ssl /usr/include/openssl /usr/local/include/openssl /usr/local/include/ssl"
+GLIB2INCLUDES="/opt/gnome/lib/glib-2.0/include /opt/gnome/include/glib-2.0 /usr/lib/glib-2.0/include /usr/include/glib-2.0"
+GLIB2CONFIG="/opt/gnome/lib/glib-2.0/include /usr/lib/glib-2.0/include"
+GLIB2LIBDIRS="/opt/gnome/lib/ /usr/lib/"
+ORBITCPPINCLUDES="/usr/include/orbitcpp-2.0 /opt/gnome/include/orbitcpp-2.0/"
+ORBITCPPCONFIG=""
+ORBITCPPLIBDIRS="/opt/gnome/lib/ /usr/lib/"
+ORBITCPPIDLS="/usr/bin/orbit-idl-2 /opt/gnome/bin/orbit-idl-2"
+ORBIT2INCLUDES="/opt/gnome/include/orbit-2.0/ /usr/include/orbit-2.0"
+ORBIT2LIBDIRS="/opt/gnome/lib/ /usr/lib/"
+LINCINCLUDES="/opt/gnome/include/linc-1.0 /usr/include/linc-1.0"
+IWEARINCDIRS="$HOME/include/ $HOME/iwear/include /usr/include"
+IWEARLIBDIRS="$HOME/lib/ $HOME/iwear/lib /usr/lib"
+IWDBINCDIRS="$HOME/include/ $HOME/iwear/include /usr/include"
+IWDBLIBDIRS="$HOME/lib/ $HOME/iwear/lib /usr/lib"
+IWSENSINCDIRS="$HOME/include/ $HOME/iwear/include /usr/include"
+IWSENSLIBDIRS="$HOME/lib/ $HOME/iwear/lib /usr/lib"
+QT3INCDIRS="/usr/lib/qt3/include/ /usr/pkg/qt3/include/ /usr/include/qt3/"
+QT3LIBDIRS="/usr/lib/qt3/lib/ /usr/pkg/qt3/lib/ /usr/lib/qt3/"
+BOOSTINCDIRS="/usr/include"
+
+XERCESLIBDIRS="/usr/lib"
+XERCESINCDIRS="/usr/include"
+
+SYSLIB="/usr/lib"
+DLLIBS="# -ldl"
+THREADLIBS="# -pthread -lpthread"
+BAIL=no
+
+# For colored output
+ESC="\033[1"
+RED="$ESC;31m"
+GRN="$ESC;32m"
+YEL="$ESC;33m"
+BLU="$ESC;34m"
+VIO="$ESC;35m"
+TUK="$ESC;36m"
+WHT="$ESC;37m"
+NOR="\033[m"
+# Set the variables if not already set
+if [ -z $CC ]
+then
+    CC=gcc
+fi
+
+if [ -z $CPP ]
+then
+    CPP=g++
+fi
+
+if [ -z $OIDL2 ]
+then
+    OIDL2=/opt/gnome/bin/orbit-idl-2
+fi
+
+
+function log
+{
+    echo $* >> $CONFLOG
+}
+
+function logecho
+{
+    echo $*
+    log $*
+}
+
+function asctoint
+{
+    ASCII=$1
+#    echo -en $ASCII | $HEXDUMP -d | head -1 | cut -d" " -f4
+    echo -en $ASCII | perl -e 'my $a = <>; print ord($a);'
+}
+
+function check_ostype # {{{
+{
+    logecho -en "Checking OS Type .. "
+    SYSTYPE=$(uname -s)
+    case $SYSTYPE in
+	Linux)
+	OS_TYPE=linux
+	;;
+	Darwin)
+	OS_TYPE=mac
+	;;
+	SunOS)
+	OS_TYPE=solaris
+	;;
+	freebsd4.6)
+	OS_TYPE=freebsd
+	;;
+	openbsd3.4)
+	OS_TYPE=openbsd
+	;;
+	*)
+	OS_TYPE=$OSTYPE
+	logecho -en ". [OS Type $OS_TYPE not supported, proceeding anyways].. "
+	;;
+    esac
+    logecho -e ." "$OS_TYPE
+} # }}}
+
+function check_dynlib # {{{
+{
+    logecho -en "Checking for dynamic library suffix .. "
+    case $OS_TYPE in
+	solaris | linux | openbsd | freebsd)
+	DYN_SUFFIX="so"
+	;;
+	mac)
+	DYN_SUFFIX="dylib"
+	;;
+	*)
+	DYN_SUFFIX="so"
+	logecho -en ". [OS Type $OS_TYPE not supported, proceeding with .so.. "
+	;;
+    esac
+    logecho -e ." "$DYN_SUFFIX
+
+    logecho -en "Checking for dynamic linker flags .. "
+    case $OS_TYPE in
+	solaris | linux | openbsd | freebsd)
+	LIBFLAGS="-shared -Wl,-warn-once,-soname,"
+	if [ "$HOSTTYPE" == x86_64 ]
+	then
+	    SYSCPPFLAGS="$SYSCPPFLAGS -fPIC"
+	    SYSCFLAGS="$SYSCFLAGS -fPIC"
+	    logecho -en "[x86_64 -fPIC]"
+	fi
+	;;
+	mac)
+	LIBFLAGS="-flat_namespace -undefined suppress -dynamiclib -install_name"
+	;;
+	*)
+	LIBFLAGS="-shared -Wl,-warn-once,-soname,"
+	logecho -en ". [OS Type $OS_TYPE not supported, proceeding with $LIBFLAGS .. "
+	;;
+    esac
+    logecho -e ." "$LIBFLAGS
+} # }}}
+
+function cleanup # {{{
+{
+    if [ -d "$C_TEMPDIR" ]
+    then
+	log "Cleaning up temporary directories..."
+	rm -r $C_TEMPDIR 2>&1 >> $CONFLOG 
+    fi
+} # }}}
+
+function check_version # {{{
+{
+    WANTED=$1
+    HAVE=$2
+    WHAT=$3
+
+    if [ -z "$4" ]
+    then
+	DISPLAY_WANTED=$WANTED
+    else
+	DISPLAY_WANTED=$4
+    fi
+
+    if [ -z "$5" ]
+    then
+	DISPLAY_HAVE=$HAVE
+    else
+	DISPLAY_HAVE=$5
+    fi
+
+    HAVE_MAJ=`echo $HAVE | cut -d"." -f1`
+    HAVE_MIN=`echo $HAVE | cut -d"." -f2`
+    HAVE_REL=`echo $HAVE | cut -d"." -f3`
+
+    WANT_MAJ=`echo $WANTED | cut -d"." -f1`
+    WANT_MIN=`echo $WANTED | cut -d"." -f2`
+    WANT_REL=`echo $WANTED | cut -d"." -f3`
+
+    VERSION_OK=yes
+
+    log -e "Checking Version of $WHAT wanting $DISPLAY_WANTED and found $DISPLAY_HAVE"
+    if [ $HAVE_MAJ -lt $WANT_MAJ ]
+    then
+	VERSION_OK=no
+	echo "fail"
+	echo "Your Major Version of $WHAT ($DISPLAY_HAVE) does not match the required one $DISPLAY_WANTED"
+	return
+    else
+	if [ $HAVE_MAJ -eq $WANT_MAJ -a $HAVE_MIN -lt $WANT_MIN ]
+	then
+	    echo "fail"
+	    echo "Your Minor Version of $WHAT ($DISPLAY_HAVE) does not match the required one $DISPLAY_WANTED"
+	    VERSION_OK=no
+	    return
+	else
+	    if [ $HAVE_MAJ -eq $WANT_MAJ -a $HAVE_MIN -eq $WANT_MIN -a $HAVE_REL -lt $WANT_REL ]
+	    then
+		echo "fail"
+		echo "Your Release Version of $WHAT ($DISPLAY_HAVE) does not match the required one $DISPLAY_WANTED"
+		VERSION_OK=no
+		return
+	    fi
+	fi
+    fi
+    
+} # }}}
+
+function toupper # {{{
+{
+sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'
+} # }}}
+
+function tolower # {{{
+{
+sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'
+} # }}}
+
+function logsetvar # {{{
+{
+    VAR=$1
+    CONT=$2
+    log -e "Setting $VAR=$CONT"
+    eval "$VAR=$CONT"
+} # }}}
+
+function search_libdir # {{{
+{
+    LFLAG=$1
+    PDIRS=$2
+    TEMPO=$C_TEMPDIR/check_lib
+    TEMPC=$C_TEMPDIR/check_lib.c
+    FOUNDLIB=""
+
+cat > $TEMPC <<XEOF
+int main ( void ) { return 0; }
+XEOF
+
+    for dir in $PDIRS
+    do
+	if [ "$dir" == "#" ]
+	then
+	    dir=""
+	fi
+	log -e "Exec (gcc $LFLAG -L$dir -o $TEMPO $TEMPC)"
+	gcc $LFLAG -L$dir -o $TEMPO $TEMPC >> $CONFLOG 2>&1
+	if [ -x "$TEMPO" ]
+	then
+	    FOUNDLIB=$dir
+	    return
+	fi
+    done	
+} # }}}
+
+function test_include # {{{
+{
+    MCC=$1
+    CFILE=$2
+    LCFLAGS=$3
+    OFILE=$4
+    TTAG=$5
+    TRIALSS=$6
+    TRIAL=""
+
+    log "Testing Program $CFILE"
+    log "Contents : "
+    cat $CFILE >> $CONFLOG
+    log "CFLAGS = $LCFLAGS"
+
+    rm -f $OFILE
+    for inc in $TRIALSS
+    do
+	if [ "$inc" == "#" ]
+	then
+	    inc=""
+	fi
+	log "Exec ($MCC $LCFLAGS $TTAG $inc -o $OFILE $CFILE)"
+	$MCC $LCFLAGS ${TTAG}${inc} -o $OFILE $CFILE >> $CONFLOG 2>&1
+	if [ -x "$OFILE" ]
+	then
+	    log "Setting TRIAL=$inc"
+	    TRIAL=$inc
+	    return
+	fi
+    done
+} # }}}
+
+# Sets BAIL=yes if the Version is wrong
+function check_gcc  #{{{
+{
+BAIL=no
+VERSION_OK=no
+WANTED_GCC=$1
+
+logecho -en "Checking for $CC >= $WANTED_GCC ... "
+if [ "$FORCEGCC" == "yes" ]
+then
+    logecho "(skipped - user override)"
+    return
+fi
+
+TEMP_C="$C_TEMPDIR/check_gcc.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_gcc.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <stdio.h>
+#ifndef __GNUC_PATCHLEVEL__
+#define __GNUC_PATCHLEVEL__ 0
+#endif
+int main ( void )
+{
+    printf("%d.%d.%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
+    return 0;
+}
+
+XEOF
+
+log -e "\nContents of $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+log -e "exec( $CC $CFLAGS $TEMP_C -o $TEMP_X )"
+$CC $CFLAGS $TEMP_C -o $TEMP_X >> $CONFLOG 2>&1 
+rm -f $TEMP_C
+if [ ! -x $TEMP_X ]
+then
+    logecho -e "Could not create executable, check compiler and CFLAGS"
+    exec echo "Stop"
+fi
+
+read GCC_VER < <($TEMP_X)
+
+    check_version $WANTED_GCC $GCC_VER "gcc"
+
+    if [ "$VERSION_OK" != "yes" ]
+    then
+	BAIL=yes
+	return
+    fi
+logecho -e  "$GCC_VER (OK)"
+
+rm -f $TEMP_X
+} #}}}
+
+# Sets BAIL=yes if the Version is wrong
+function check_gpp  #{{{
+{
+BAIL=no
+WANTED_GPP=$1
+
+logecho -en "Checking for $CPP >= $WANTED_GPP ... "
+
+if [ "$FORCEGPP" == "yes" ]
+then
+    echo "(skipped - user override)"
+    return
+fi
+
+
+TEMP_CPP="$C_TEMPDIR/check_gcc.cpp"
+TEMP_X=`mktemp $C_TEMPDIR/check_gcc.XXXXXX`
+
+cat > $TEMP_CPP <<XEOF
+#include <stdio.h>
+#include <iostream>
+#ifndef __GNUC_PATCHLEVEL__
+#define __GNUC_PATCHLEVEL__ 0
+#endif
+
+int main ( void )
+{
+    printf("%d.%d.%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
+    return 0;
+}
+
+XEOF
+log -e "\nContents of $TEMP_CPP"
+cat $TEMP_CPP >> $CONFLOG
+log -e "Exec( $CPP $CPPFLAGS $TEMP_CPP -o $TEMP_X )"
+$CPP $CPPFLAGS $TEMP_CPP -o $TEMP_X >> $CONFLOG 2>&1
+rm -f $TEMP_CPP
+
+if [ ! -x $TEMP_X ]
+then
+    BAIL=yes
+    logecho -e "\nCould not create a program with $CPP please verify that its working properly"
+    return
+fi
+
+read GPP_VER < <($TEMP_X 2>> $CONFLOG)
+
+    if [ -z "$GPP_VER" ]
+    then
+	logecho -e "\nWe were able to build an executable, but the executable failed to run"
+	BAIL=yes
+	return
+    fi
+    
+    check_version $WANTED_GPP $GPP_VER "g++"
+
+    if [ "$VERSION_OK" != "yes" ]
+    then
+	BAIL=yes
+	return
+    fi
+
+logecho "$GPP_VER (OK)"
+
+logecho -en "Checking for $CPP extra warning flag... "
+
+GPP_MAJ=`echo $GPP_VER | cut -d"." -f1`
+GPP_MIN=`echo $GPP_VER | cut -d"." -f2`
+GPP_REL=`echo $GPP_VER | cut -d"." -f3`
+
+WEXTRA="-W"
+if [ $GPP_MAJ -ge 4 ]
+then
+    WEXTRA="-Wextra"
+else
+    if [ $GPP_MIN -ge 4 ]
+    then
+	WEXTRA="-Wextra"
+    fi
+fi
+
+logecho " $WEXTRA"
+
+rm -f $TEMP_X
+
+} #}}}
+
+# Sets BAIL=yes if the Version is wrong
+function check_gmake #{{{
+{
+    MAKE=`which gmake`
+    if [ -z $MAKE ]
+    then
+	MAKE=`which make`
+    fi
+
+    log -e "Found a make at $MAKE"
+
+    WANTED_VER=$1
+
+    logecho -n "Checking for GNU Make >= $WANTED_VER ... "
+
+    VER=`$MAKE --version 2>/dev/null | grep GNU | head -1 | sed 's/[^0-9\.]//g'`
+
+    if [ -z "$VER" ]
+    then
+	echo "fail"
+	echo "This Environment is compatible with GNU Make only."
+        echo "Please install GNU Make or provide a link called gmake within \$PATH"
+	BAIL=yes
+	return 1	
+    fi
+
+    check_version $WANTED_VER $VER "gmake"
+
+    if [ "$VERSION_OK" != "yes" ]
+    then
+	BAIL=yes
+	return
+    fi
+
+    logecho -e "$VER (OK)"
+    MAKEMD5=$(md5sum $MAKE | cut -d" " -f1)
+    if [ -z "$MAKEMD5" ]
+    then
+	MAKEMD5=$(md5 $MAKE | cut -d" " -f1)
+    fi
+
+    case $MAKEMD5 in
+	55abf10fc1cf2f59662a28662a2931b2 | 4efe0480f7fa6589ff382dcfdc5231a2 | e4014aa543f1e2e9fec083773af33385 | 1dd8dd18455acfe252a1f31d071748cb | 1c46755ef3c6ddf79321848af77341be | eae6e72fbfc491d7490df4fb34d5c4a9 | 2b33c6b8a6b2d2fd577d880d1f930a65 | 26b6db058718fb69be92b2b0995a0983 )
+	BAIL=yes
+
+	echo 
+	echo "Though we have detected a make version that satisfies the version"
+	echo "required, it is in a blacklist of buggy make versions. We highly"
+	echo "recommend that you upgrade your make version, since those make version"
+	echo "wont work with the iwear makefiles"
+	;;
+	*)
+#	echo "md5sum : $MAKEMD5"
+	;;
+    esac
+
+} #}}}
+
+# Sets $PKG_CONFIG to the pkg-config binary, leaves it empty if not present or
+# not to be used by user override
+function check_pkg_config #{{{
+{
+    PKG_CONFIG=`which pkg-config 2>/dev/null`
+
+    logecho -n "Checking for pkg-config ... "
+    if [ -z "$PKG_CONFIG" ]
+    then
+	logecho "no"
+    else
+	if [ "$NO_PKG_CONFIG" == "yes" ]
+	then
+	    logecho "skipped (user override)"
+	    PKG_CONFIG=""
+	else
+	    logecho "yes ($PKG_CONFIG)"
+	fi
+    fi
+} #}}}
+
+# The script needs sed sometimes
+function check_sed #{{{
+{
+    logecho -en "Checking for sed ... "
+    SED=`which sed 2>/dev/null`
+    if [ -z "$SED" ]
+    then
+	BAIL="yes"
+	echo -e $RED
+	logecho -n "(fail)"" "
+	echo -en $YEL
+        logecho -n "No sed in \$PATH"
+        echo -e $NOR
+        logecho "($PATH)"
+	echo -e $YEL
+	logecho "$0 needs sed in order to continue."
+	logecho "Please install sed, add its location to the path," 
+	logecho "or create a symlink within the path to a functional sed"
+	echo -e $NOR
+	return
+    fi
+    logecho "(OK)"
+} # }}}
+
+function check_mktemp #{{{
+{
+    logecho -en "Checking for mktemp ... "
+    mktemp=`which mktemp 2>/dev/null`
+    if [ -z "$mktemp" ]
+    then
+	BAIL="yes"
+	echo -e $RED
+	logecho -n "(fail)"" "
+	echo -en $YEL
+        logecho -n "No mktemp in \$PATH"
+        echo -e $NOR
+        logecho "($PATH)"
+	echo -e $YEL
+	logecho "$0 needs mktemp in order to continue."
+	logecho "Please install mktemp, add its location to the path," 
+	logecho "or create a symlink within the path to a functional mktemp"
+	echo -e $NOR
+	return
+    fi
+    logecho "(OK)"
+} # }}}
+
+# Check for installation of pgsql libraries and the headers
+# sets PG_INCLUDE and PG_LIBDIR and BAIL if not found or version too old
+function check_pgsql # {{{
+{
+    WANTED_VER=$1
+
+    echo -en "Checking for PostgreSQL >= $WANTED_VER ... "
+    PG_CONFIG=`which pg__config 2>/dev/null`
+
+    if [ -z "$PG_CONFIG" ]
+    then
+	logecho -en "(no pg_config) "
+	TEMP_C="$C_TEMPDIR/check_libpq.c"
+	TEMP_X=`mktemp $C_TEMPDIR/check_libpq.XXXXXX`
+	cat > $TEMP_C <<XEOF
+	int main ( void )
+	{
+	    return 0;
+	}
+
+XEOF
+	log -e "Contents of $TEMP_C"
+	cat $TEMP_C >> $CONFLOG
+	log -e "ATTEMPTING TO FIND DIRECTORIES VIA TRIAL COMPILE"
+	test_include $CC $TEMP_C "$CFLAGS -lpq" $TEMP_X -L "$PQLIBDIRS"
+	log -e "Found PG_LIBDIR=$TRIAL"
+	PG_LIBDIR=$TRIAL
+	if [ -z "$PG_LIBDIR" ]
+	then
+	    logecho "failed. Could not find directory where libpq.so lives in"
+	    BAIL=yes
+	    return
+	fi
+######-----------------------------------------------------------	
+	log -e "Trial compiling for header files"
+	cat > $TEMP_C <<XEOF
+	#include <libpq-fe.h>
+	#include <pg_config.h>
+	int main ( void )
+	{
+	    printf(PG_VERSION);
+	    return 0;
+	}
+XEOF
+	log -e "Contents of $TEMP_C"
+	cat $TEMP_C >> $CONFLOG
+
+	test_include $CC $TEMP_C "$CFLAGS" $TEMP_X -I "$PQINCDIRS"
+	PG_INCLUDE=$TRIAL
+	if [ -x "$TEMP_X" ]
+	then
+	    PG_VER=`$TEMP_X`
+	fi
+
+	log -e "TEST INCLUDE COMPILE $PG_INCLUDE"
+	log -e "PG_VER=$PG_VER"
+
+	if [ -z "$PG_INCLUDE" -o -z "$PG_VER" ]
+	then
+	    logecho "\nfailed. Could not find directory where libpq-fe.h lives in"
+	    BAIL=yes
+	    return
+	fi
+
+    else
+	PG_VER=`$PG_CONFIG --version | cut -d" " -f2-`
+	PG_INCLUDE=`$PG_CONFIG --includedir`
+	PG_LIBDIR=`$PG_CONFIG --libdir`
+	log -e "pg_config found, getting dirs and flags from there..."
+	log -e "Setting PG_VER=$PG_VER"
+	log -e "Setting PG_INCLUDE=$PG_INCLUDE"
+	log -e "Setting PG_LIBDIR=$PG_LIBDIR"
+    fi
+    
+
+    check_version $WANTED_VER $PG_VER "PostgreSQL" 
+    if [ "$VERSION_OK" != "yes" ]
+    then
+	BAIL=yes
+	return
+    fi
+
+    logecho -e "$PG_VER (OK)"
+} # }}}
+
+function check_libpq # {{{
+{
+    logecho -en "Checking for usable libpq ... "
+
+TEMP_C="$C_TEMPDIR/check_libpq.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_libpq.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <libpq-fe.h>
+int main ( void )
+{
+    PQconnectStart("Hello World");
+    return 0;
+}
+XEOF
+log -e "Contents of $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+log -e "Exec( $CC $CFLAGS -I $PG_INCLUDE -L$PG_LIBDIR -lpq $TEMP_C -o $TEMP_X )"
+$CC $CFLAGS -I $PG_INCLUDE -L$PG_LIBDIR -lpq $TEMP_C -o $TEMP_X >> $CONFLOG 2>&1 
+
+if [ ! -x "$TEMP_X" ]
+then
+    logecho "fail"
+    BAIL=yes
+    logecho "We were not able to compile the test program for libpq"
+fi
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+logecho "(OK)"
+
+} #}}}
+
+function check_linc # {{{
+{
+logecho -en "Checking linc includes... "
+
+TEMP_C="$C_TEMPDIR/check_linc.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_linc.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <linc/linc.h>
+int main ( void )
+{
+    return 0;
+}
+XEOF
+log -e "Contents of $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+
+test_include $CC $TEMP_C "-I $GLIB2_CONFIG -I $GLIB2_INCLUDE" $TEMP_X -I "$LINCINCLUDES"
+LINC_INCLUDE=$TRIAL
+log -e "Succes, set LINC_INCLUDE=$LINC_INCLUDE"
+
+if [ ! -x "$TEMP_X" ]
+then
+    logecho "fail"
+    BAIL=yes
+    logecho "We were not able to compile the test program for linc.  Have you installed the Headers (-devel package of your distro) ?"
+else
+    logecho "(OK)"
+fi
+#
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_iwear # {{{
+{
+    WANTED_VER=$1
+    
+
+    TEMP_C="$C_TEMPDIR/check_iwear.c"
+    TEMP_X=`mktemp $C_TEMPDIR/check_iwear.XXXXXX`
+
+    cat > $TEMP_C <<XEOF
+#include <iwear/config.h>
+
+int main ( void )
+{
+    printf("%lu.%lu.%lu\n",IWEAR_MAJOR,IWEAR_MINOR,IWEAR_RELEASE);
+    return 0;
+}
+XEOF
+
+    logecho -en "Checking for iWear core libraries ... "
+    search_libdir "-liwear_core" "$IWEARLIBDIRS"
+
+    logsetvar IWEAR_LIBDIR $FOUNDLIB
+
+    if [ -z "$FOUNDLIB" ]
+    then
+	logecho -e "fail"
+	logecho -e "We were not able to generate a check program for $CHECKME."
+        logecho -e "please see $CONFLOG for details"
+	BAIL=yes
+	return
+    fi
+    logecho " (OK)"
+
+    logecho -en "Checking for iWear core includes ... "
+
+    log -e "Trial compiling $TEMP_C"
+    cat $TEMP_C >> $CONFLOG
+
+    test_include $CC $TEMP_C "$DLLIB -L$IWEAR_LIBDIR -liwear_core" $TEMP_X -I "$IWEARINCDIRS"
+    IWEAR_INCLUDE=$TRIAL
+    log -e "Succes, set IWEAR_INCLUDE=$IWEAR_INCLUDE"
+
+    if [ ! -x "$TEMP_X" ]
+    then
+	logecho "fail"
+	BAIL=yes
+	logecho "We were not able to compile the test program for iWear core. Have you installed the Headers (-devel package of your distro) ?"
+    else
+	logecho -e "yes ($IWEAR_INCLUDE)"
+	logecho -en "Checking for iWear core >= $WANTED_VER ... "
+	IWEAR_VER=`$TEMP_X`
+	check_version $WANTED_VER $IWEAR_VER "iWear"  $WANTED_VER $IWEAR_VER
+	if [ "$VERSION_OK" != "yes" ]
+	then
+	    BAIL=yes
+	fi
+fi
+#    echo -e "Want : $WANTED_VER"
+#    echo -e "Have : $SSL_VER"
+ 
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+if [ "$BAIL" != "yes" ]
+then
+    logecho "$IWEAR_VER (OK)"
+fi
+
+} #}}}
+
+function check_boost # {{{
+{
+    WANTED_VER=$1
+    
+
+    TEMP_C="$C_TEMPDIR/check_boost.cpp"
+    TEMP_X=`mktemp $C_TEMPDIR/check_boost.XXXXXX`
+
+    cat > $TEMP_C <<XEOF
+#include <boost/version.hpp>
+#include <iostream>
+using namespace std;
+
+int main ( void )
+{
+    cout << 
+    BOOST_VERSION / 100000 << "." << 
+    BOOST_VERSION / 100 % 1000 << "." << 
+    BOOST_VERSION % 100 << endl;
+    return 0;
+}
+XEOF
+
+    logecho -en "Checking for boost includes ... "
+
+    log -e "Trial compiling $TEMP_C"
+    cat $TEMP_C >> $CONFLOG
+
+    test_include $CPP $TEMP_C "$DLLIB" $TEMP_X -I "$BOOSTINCDIRS"
+    boost_INCLUDE=$TRIAL
+    log -e "Succes, set BOOST_INCLUDE=$BOOST_INCLUDE"
+
+    if [ ! -x "$TEMP_X" ]
+    then
+	logecho "fail"
+	BAIL=yes
+	logecho "We were not able to compile the test program for boost headers. Have you installed the Headers (-devel package of your distro) ?"
+    else
+	logecho -e "yes ($BOOST_INCLUDE)"
+	logecho -en "Checking for boost >= $WANTED_VER ... "
+	BOOST_VER=`$TEMP_X`
+	check_version $WANTED_VER $BOOST_VER "boost"  $WANTED_VER $BOOST_VER
+	if [ "$VERSION_OK" != "yes" ]
+	then
+	    BAIL=yes
+	fi
+fi
+#    echo -e "Want : $WANTED_VER"
+#    echo -e "Have : $SSL_VER"
+ 
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+if [ "$BAIL" != "yes" ]
+then
+    logecho "$BOOST_VER (OK)"
+fi
+
+} #}}}
+
+function check_iwdb # {{{
+{
+    WANTED_VER=$1
+    
+
+    TEMP_C="$C_TEMPDIR/check_iwdb.c"
+    TEMP_X=`mktemp $C_TEMPDIR/check_iwdb.XXXXXX`
+
+    cat > $TEMP_C <<XEOF
+#include <dbclasses/config.h>
+
+int main ( void )
+{
+    printf("%lu.%lu.%lu\n",DBCLASSES_MAJOR,DBCLASSES_MINOR,DBCLASSES_RELEASE);
+    return 0;
+}
+XEOF
+
+    logecho -en "Checking for iwear database libraries ... "
+    search_libdir "-liwdb" "$IWDBLIBDIRS"
+
+    logsetvar IWDB_LIBDIR $FOUNDLIB
+
+    if [ -z "$FOUNDLIB" ]
+    then
+	logecho -e "fail"
+	logecho -e "We were not able to generate a check program for $CHECKME."
+        logecho -e "please see $CONFLOG for details"
+	BAIL=yes
+	return
+    fi
+    logecho " (OK)"
+
+    logecho -en "Checking for iwear database includes ... "
+
+    log -e "Trial compiling $TEMP_C"
+    cat $TEMP_C >> $CONFLOG
+
+    test_include $CC $TEMP_C "$DLLIB -L$IWDB_LIBDIR -liwdb" $TEMP_X -I "$IWDBINCDIRS"
+    IWDB_INCLUDE=$TRIAL
+    log -e "Succes, set IWDB_INCLUDE=$IWDB_INCLUDE"
+
+    if [ ! -x "$TEMP_X" ]
+    then
+	logecho "fail"
+	BAIL=yes
+	logecho "We were not able to compile the test program for iwdb core. Have you installed the Headers (-devel package of your distro) ?"
+    else
+	logecho -e "yes ($IWDB_INCLUDE)"
+	logecho -en "Checking for iwdb core >= $WANTED_VER ... "
+	IWDB_VER=`$TEMP_X`
+	check_version $WANTED_VER $IWDB_VER "iwdb"  $WANTED_VER $IWDB_VER
+	if [ "$VERSION_OK" != "yes" ]
+	then
+	    BAIL=yes
+	fi
+fi
+#    echo -e "Want : $WANTED_VER"
+#    echo -e "Have : $SSL_VER"
+ 
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+if [ "$BAIL" != "yes" ]
+then
+    logecho "$IWDB_VER (OK)"
+fi
+
+} #}}}
+
+function check_iwsens # {{{
+{
+    WANTED_VER=$1
+    
+
+    TEMP_C="$C_TEMPDIR/check_iwsens.c"
+    TEMP_X=`mktemp $C_TEMPDIR/check_iwsens.XXXXXX`
+
+    cat > $TEMP_C <<XEOF
+#include <iwsens/config.h>
+
+int main ( void )
+{
+    printf("%lu.%lu.%lu\n",IWSENS_MAJOR,IWSENS_MINOR,IWSENS_RELEASE);
+    return 0;
+}
+XEOF
+
+    logecho -en "Checking for iwear sensor core libraries ... "
+    search_libdir "-liwsens" "$IWSENSLIBDIRS"
+
+    logsetvar IWSENS_LIBDIR $FOUNDLIB
+
+    if [ -z "$FOUNDLIB" ]
+    then
+	logecho -e "fail"
+	logecho -e "We were not able to generate a check program for $CHECKME."
+        logecho -e "please see $CONFLOG for details"
+	BAIL=yes
+	return
+    fi
+    logecho " (OK)"
+
+    logecho -en "Checking for iwear sensor core includes ... "
+
+    log -e "Trial compiling $TEMP_C"
+    cat $TEMP_C >> $CONFLOG
+
+    test_include $CC $TEMP_C "$DLLIB -L$IWSENS_LIBDIR -liwsens" $TEMP_X -I "$IWSENSINCDIRS"
+    IWSENS_INCLUDE=$TRIAL
+    log -e "Succes, set IWSENS_INCLUDE=$IWSENS_INCLUDE"
+
+    if [ ! -x "$TEMP_X" ]
+    then
+	logecho "fail"
+	BAIL=yes
+	logecho "We were not able to compile the test program for iwsens core. Have you installed the Headers (-devel package of your distro) ?"
+    else
+	logecho -e "yes ($IWSENS_INCLUDE)"
+	logecho -en "Checking for iwsens core >= $WANTED_VER ... "
+	IWSENS_VER=`$TEMP_X`
+	check_version $WANTED_VER $IWSENS_VER "iwsens"  $WANTED_VER $IWSENS_VER
+	if [ "$VERSION_OK" != "yes" ]
+	then
+	    BAIL=yes
+	fi
+fi
+#    echo -e "Want : $WANTED_VER"
+#    echo -e "Have : $SSL_VER"
+ 
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+if [ "$BAIL" != "yes" ]
+then
+    logecho "$IWSENS_VER (OK)"
+fi
+
+} #}}}
+
+function check_ssl # {{{
+{
+    WANTED_VER=$1
+    RW=$1
+    NUMVER=`echo $WANTED_VER | sed 's/[^0-9\.]//g'`
+    SUBVER=`echo $WANTED_VER | sed 's/[0-9\.]//g'`
+    REL=`asctoint $SUBVER`
+    WANTED_VER="$NUMVER$REL"
+    
+    logecho -en "Checking for OpenSSL includes ... "
+
+    TEMP_C="$C_TEMPDIR/check_ssl.c"
+    TEMP_X=`mktemp $C_TEMPDIR/check_ssl.XXXXXX`
+
+    cat > $TEMP_C <<XEOF
+#include <opensslv.h>
+#include <md5.h>
+#include <stdio.h>
+
+int main ( void )
+{
+    MD5_CTX ctx;
+    MD5_Init(&ctx);
+// e.g. 0x0090702fL
+// 10 for 1.
+
+unsigned long int over = OPENSSL_VERSION_NUMBER;
+//    over = 0x1101104fL; // 1.10.11d
+unsigned long int major = (over & 0xF0000000L) >> 28;
+if ( major > 9 ) major -= 6;
+
+unsigned long int minor = (over & 0x0FF00000L) >> 20;
+if ( minor > 9 ) minor -= 6;
+
+unsigned long int release = (over & 0x000FF000L) >> 12;
+if ( release > 9 ) release -= 6;
+
+unsigned long int patch = (over & 0x000000F0L) >> 4;
+printf("%lu.%lu.%lu%c\n",major,minor,release,(char)(96+patch));
+return 0;
+}
+XEOF
+
+log -e "Trial compiling $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+
+test_include $CC $TEMP_C "$DLLIB -lcrypto -lssl" $TEMP_X -I "$SSLINCDIRS"
+SSL_INCLUDE=$TRIAL
+log -e "Succes, set SSL_INCLUDE=$SSL_INCLUDE"
+
+if [ ! -x "$TEMP_X" ]
+then
+    logecho "fail"
+    BAIL=yes
+    logecho "We were not able to compile the test program for openssl. Have you installed the Headers (-devel package of your distro) ?"
+else
+    logecho -e "yes ($SSL_INCLUDE)"
+    logecho -en "Checking for OpenSSL >= $RW ... "
+    SSL_VER="0.9.7g"
+    SSL_VER=`$TEMP_X`
+    SW=$SSL_VER
+    NUMVER=`echo $SSL_VER | sed 's/[^0-9\.]//g'`
+    SUBVER=`echo $SSL_VER | sed 's/[0-9\.]//g'`
+    REL=`asctoint $SUBVER`
+    SSL_VER="$NUMVER$REL"
+    check_version $WANTED_VER $SSL_VER "OpenSSL"  $RW $SW
+    if [ "$VERSION_OK" != "yes" ]
+    then
+	BAIL=yes
+    fi
+fi
+#    echo -e "Want : $WANTED_VER"
+#    echo -e "Have : $SSL_VER"
+ 
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+if [ "$BAIL" != "yes" ]
+then
+    logecho "$SW (OK)"
+fi
+
+} #}}}
+
+function check_glib2 # {{{
+{
+    WANTED_VER=$1
+    
+    logecho -en "Checking for glib2 includes ... "
+
+    TEMP_C="$C_TEMPDIR/check_glib2.c"
+    TEMP_X=`mktemp $C_TEMPDIR/check_ssl.XXXXXX`
+
+    cat > $TEMP_C <<XEOF
+#define __G_LIB_H__
+#include <glib.h>
+
+#include <unistd.h>
+int main ( void )
+{
+    return 0;
+}
+XEOF
+
+log -e "Trial compiling $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+
+test_include $CC $TEMP_C "" $TEMP_X -I "$GLIB2INCLUDES"
+GLIB2_INCLUDE=$TRIAL
+log -e "Succes, set GLIB2_INCLUDE=$GLIB2_INCLUDE"
+
+if [ ! -x "$TEMP_X" ]
+then
+    logecho "fail"
+    BAIL=yes
+    logecho "We were not able to compile the test program for glib2.  Have you installed the Headers (-devel package of your distro) ?"
+    logecho "Could not find glib.h in any of $GLIB2INCLUDES"
+    return
+fi
+ 
+    cat > $TEMP_C <<XEOF
+#include <glibconfig.h>
+int main ( void )
+{
+    return 0;
+//    printf("%d.%d.%d\n", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION)
+}
+XEOF
+
+log -e "Trial compiling $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+test_include $CC $TEMP_C "-I $GLIB2_INCLUDE" $TEMP_X -I "$GLIB2CONFIG"
+GLIB2_CONFIG=$TRIAL
+log -e "GLIB2_CONFIG=$GLIB2_CONFIG"
+
+if [ -z "$GLIB2_CONFIG" ]
+then
+    BAIL=yes
+    logecho -e "fail"
+    logecho -e "Could not find glibconfig.h in any of $GLIB2CONFIG"
+    return
+fi
+
+    cat > $TEMP_C <<XEOF
+#include <glib/gutils.h>
+int main ( void )
+{
+    printf("%d.%d.%d\n", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
+    return 0;
+}
+XEOF
+
+log -e "Trial compiling $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+
+test_include $CC $TEMP_C "-I $GLIB2_INCLUDE  -I $GLIB2_CONFIG" $TEMP_X -L "$GLIB2LIBDIRS"
+GLIB2_LIBDIR=$TRIAL
+
+
+if [ -z "$GLIB2_LIBDIR" ]
+then
+    BAIL=yes
+    logecho -e "fail"
+    logecho -e "Could not find libglib-2.0 in any of $GLIB2LIBDIRS"
+    return
+fi
+
+    GLIB2_VER=`$TEMP_X`
+    check_version $WANTED_VER $GLIB2_VER "glib2"
+
+if [ "$VERSION_OK" != "yes" ]
+then
+    BAIL=yes
+fi
+
+if [ "$BAIL" != "yes" ]
+then
+    logecho "$GLIB2_VER (OK)"
+fi
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_orbit2 # {{{
+{
+    WANTED_VER=$1
+    
+    logecho -en "Checking for ORBit2 includes ... "
+
+    TEMP_C="$C_TEMPDIR/check_ORBit2.c"
+    TEMP_X=`mktemp $C_TEMPDIR/check_ORBit2.XXXXXX`
+
+    cat > $TEMP_C <<XEOF
+#include <orbit/orb-core/corba-defs.h>
+
+#include <unistd.h>
+int main ( void )
+{
+    return 0;
+}
+XEOF
+
+log -e "Trial compiling $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+
+if [ -z "$LINC_INCLUDE" ]
+then
+    LINC_INCLUDE="/usr/include/linc-1.0"
+fi
+
+test_include $CC $TEMP_C "-I $LINC_INCLUDE -I $GLIB2_CONFIG -I $GLIB2_INCLUDE" $TEMP_X -I "$ORBIT2INCLUDES"
+ORBIT2_INCLUDE=$TRIAL
+log -e "Succes, set ORBIT2_INCLUDE=$ORBIT2_INCLUDE"
+
+if [ ! -x "$TEMP_X" ]
+then
+    logecho "fail"
+    BAIL=yes
+    logecho "We were not able to compile the test program for ORBit2.  Have you installed the Headers (-devel package of your distro) ?"
+else
+    logecho "(OK)"
+fi
+############# DONE CHECKING FOR HEADERS 
+    cat > $TEMP_C <<XEOF
+#include <orbit/orbit-config.h>
+int main ( void )
+{
+    printf("%d.%d.%d\n", ORBIT_MAJOR_VERSION, ORBIT_MINOR_VERSION, ORBIT_MICRO_VERSION);
+    return 0;
+}
+XEOF
+############# CHECKING LIBRARY PATH AND VERSION
+logecho -en "Checking for ORBit2 >= $WANTED_VER ... "
+log -e "Trial compiling $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+
+if [ -z "$LINC_INCLUDE" ]
+then
+    LINC_INCLUDE="/usr/include/linc-1.0"
+fi
+test_include $CC $TEMP_C "-lORBit-2 -I $LINC_INCLUDE -I $ORBIT2_INCLUDE" $TEMP_X -L "$ORBIT2LIBDIRS"
+ORBIT2_LIBDIR=$TRIAL
+log -e "Setting ORBIT2_LIBDIR=$TRIAL"
+
+if [ -z "$ORBIT2_LIBDIR" ]
+then
+    BAIL=yes
+    logecho -e "fail"
+    logecho -e "Could not find libORBit-2 in any of $ORBIT2LIBDIRS"
+    return
+fi
+
+    ORBIT2_VER=`$TEMP_X`
+    check_version $WANTED_VER $ORBIT2_VER "ORBit2"
+
+if [ "$VERSION_OK" != "yes" ]
+then
+    BAIL=yes
+fi
+
+if [ "$BAIL" != "yes" ]
+then
+    logecho "$ORBIT2_VER (OK)"
+fi
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_orbitcpp # {{{
+{
+    WANTED_VER=$1
+    
+    logecho -en "Checking for orbitcpp includes ... "
+
+    TEMP_C="$C_TEMPDIR/check_orbitcpp.c"
+    TEMP_X=`mktemp $C_TEMPDIR/check_orbitcpp.XXXXXX`
+
+    cat > $TEMP_C <<XEOF
+#include <orbitcpp/orb-cpp/orbitcpp.h>
+
+#include <unistd.h>
+int main ( void )
+{
+    return 0;
+}
+XEOF
+
+log -e "Trial compiling $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+
+if [ -z "$LINC_INCLUDE" ]
+then
+    LINC_INCLUDE="/usr/include/linc-1.0"
+fi
+test_include $CPP $TEMP_C "-I $LINC_INCLUDE -I $ORBIT2_INCLUDE -I $GLIB2_CONFIG -I $GLIB2_INCLUDE" $TEMP_X -I "$ORBITCPPINCLUDES"
+ORBITCPP_INCLUDE=$TRIAL
+log -e "Succes, set ORBITCPP_INCLUDE=$ORBITCPP_INCLUDE"
+
+if [ ! -x "$TEMP_X" ]
+then
+    logecho "fail"
+    BAIL=yes
+    logecho "We were not able to compile the test program for orbitcpp.  Have you installed the Headers (-devel package of your distro) ?"
+fi
+ 
+    cat > $TEMP_C <<XEOF
+#include <orbitcpp/orb-cpp/orbitcpp_constants.h>
+#include <stdio.h>
+using namespace _orbitcpp;
+int main ( void )
+{
+    printf("%d.%d.%d\n", LIB_MAJOR_VERSION, LIB_MINOR_VERSION, LIB_MICRO_VERSION);
+    return 0;
+}
+XEOF
+
+log -e "Trial compiling $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+
+test_include $CPP $TEMP_C "-lORBit-2-cpp -I $ORBITCPP_INCLUDE" $TEMP_X -L "$ORBITCPPLIBDIRS"
+ORBITCPP_LIBDIR=$TRIAL
+log -e "ORBITCPP_LIBDIR=$ORBITCPP_LIBDIR"
+
+if [ -z "$ORBITCPP_LIBDIR" ]
+then
+    BAIL=yes
+    logecho -e "fail"
+    logecho -e "Could not find libORBit-2-cpp in any of $ORBITCPPLIBDIRS"
+    return
+fi
+
+    ORBITCPP_VER=`$TEMP_X`
+    check_version $WANTED_VER $ORBITCPP_VER "orbitcpp"
+
+if [ "$VERSION_OK" != "yes" ]
+then
+    BAIL=yes
+fi
+
+if [ "$BAIL" != "yes" ]
+then
+    logecho "$ORBITCPP_VER (OK)"
+fi
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+logecho -en "Checking for orbit-idl-2 ... "
+for idl in $ORBITCPPIDLS 
+do
+    if [ -x $idl ]
+    then
+	ORBITCPPIDL=$idl
+    fi
+done
+
+if [ -z "$ORBITCPPIDL" ]
+then
+    echo "none"
+    echo -e "Could not find orbit-idl-2 in any of $ORBITCPPIDLS"
+    BAIL=yes
+else
+    logecho "yes ($ORBITCPPIDL)"
+fi
+} #}}}
+
+function check_strnlen # {{{
+{
+logecho -en "Checking for strnlen ... "
+
+TEMP_C="$C_TEMPDIR/check_strnlen.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_strnlen.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <string.h>
+int main ( void )
+{
+    strnlen(NULL,0);
+}
+
+XEOF
+log -e "Test Program $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+log -e "Exec( $CC $TEMP_C -o $TEMP_X )"
+$CC $TEMP_C -o $TEMP_X >> $CONFLOG 2>&1 
+
+if [ -x "$TEMP_X" ]
+then
+    HAVE_STRNLEN="yes"
+    logecho "yes"
+else
+    HAVE_STRNLEN="no"
+    logecho "no"
+fi
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_clock_gettime # {{{
+{
+logecho -en "Checking for clock_gettime ... "
+
+TEMP_C="$C_TEMPDIR/check_clock_gettime.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_clock_gettime.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <time.h>
+int main ( void )
+{
+    clock_gettime(CLOCK_REALTIME,NULL);
+}
+
+XEOF
+log -e "Test Program $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+log -e "Exec( $CC $TEMP_C -o $TEMP_X )"
+if [ "$OS_TYPE" == "linux" ]
+then
+    $CC -lrt $TEMP_C -o $TEMP_X >> $CONFLOG 2>&1 
+else
+    $CC $TEMP_C -o $TEMP_X >> $CONFLOG 2>&1 
+fi
+
+if [ -x "$TEMP_X" ]
+then
+    HAVE_CLOCK_GETTIME="yes"
+    logecho "yes"
+else
+    HAVE_CLOCK_GETTIME="no"
+    logecho "no"
+fi
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_strcasestr # {{{
+{
+logecho -en "Checking for strcasestr ... "
+
+TEMP_C="$C_TEMPDIR/check_strcasestr.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_strcasestr.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <string.h>
+int main ( void )
+{
+    strcasestr(NULL,NULL);
+}
+
+XEOF
+log -e "Test Program $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+log -e "Exec( $CC $TEMP_C -o $TEMP_X )"
+$CC $TEMP_C -o $TEMP_X >> $CONFLOG 2>&1 
+
+if [ -x "$TEMP_X" ]
+then
+    HAVE_STRCASESTR="yes"
+    echo "yes"
+else
+    HAVE_STRCASESTR="no"
+    echo "no"
+fi
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_vasprintf # {{{
+{
+logecho -en "Checking for vasprintf ... "
+
+TEMP_C="$C_TEMPDIR/check_vasprintf.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_vasprintf.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdarg.h>
+int main ( void )
+{
+    vasprintf(NULL,0);
+}
+
+XEOF
+log -e "Test Program $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+log -e "Exec( $CC $TEMP_C -o $TEMP_X )"
+$CC $TEMP_C -o $TEMP_X >> $CONFLOG 2>&1 
+
+if [ -x "$TEMP_X" ]
+then
+    HAVE_VASPRINTF="yes"
+    logecho "yes"
+else
+    HAVE_VASPRINTF="no"
+    logecho "no"
+fi
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_strerror_r # {{{
+{
+logecho -en "Checking for strerror_r ... "
+
+TEMP_C="$C_TEMPDIR/check_strerror_r.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_strerror_r.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <string.h>
+int main ( void )
+{
+    strerror_r(0,NULL,0);
+}
+
+XEOF
+log -e "Test Program $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+log -e "Exec( $CC $TEMP_C -o $TEMP_X )"
+$CC $TEMP_C -o $TEMP_X >> $CONFLOG 2>&1 
+
+if [ -x "$TEMP_X" ]
+then
+    HAVE_STRERROR_R="yes"
+    logecho "yes"
+else
+    HAVE_STRERROR_R="no"
+    logecho "no"
+fi
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_wireless # {{{
+{
+case $OS_TYPE in
+    linux)
+    check_wireless_linux
+    ;;
+    mac)
+    logecho -e $RED
+    logecho
+    logecho "Sorry, we dont have wireless support for MacOSX yet."
+    logecho "It is heavily beeing worked on, please check a newer release."
+    logecho -e $NOR
+    ;;
+    *)
+    logecho -e $RED
+    logecho
+    logecho "Your Hosttype is not supportted for wireless operations"
+    logecho -e $NOR
+    ;;
+esac
+
+if [ "$HAVE_WIRELESS" != "yes" ]
+then
+    logecho "Proceeding without wireless support"
+else
+    logecho "Proceeding with wireless support"
+fi
+
+} # }}}
+
+function check_wireless_linux # {{{
+{
+logecho -en "Checking for Linux wireless headers... "
+
+TEMP_C="$C_TEMPDIR/check_wireless.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_wireless.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <sys/socket.h>
+#include <linux/wireless.h>
+int main ( void )
+{
+    printf("%d",WIRELESS_EXT);
+}
+
+XEOF
+log -e "Test Program $TEMP_C"
+cat $TEMP_C >> $CONFLOG
+log -e "Exec( $CC $TEMP_C -o $TEMP_X )"
+$CC $TEMP_C -o $TEMP_X >> $CONFLOG 2>&1 
+
+if [ -x "$TEMP_X" ]
+then
+    HAVE_WIRELESS="yes"
+    EXT_VER=$($TEMP_X)
+    logecho "yes (wireless extensions $EXT_VER)"
+else
+    HAVE_WIRELESS="no"
+    logecho "no"
+    logecho -e $RED
+    logecho -e "We were unable to find the Linux Wireless Extension Headers"
+    logecho -e $NOR
+#    BAIL="yes"
+fi
+
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_dlopen # {{{
+{
+logecho -en "Checking for dlopen ... "
+
+TEMP_C="$C_TEMPDIR/check_dlopen.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_dlopen.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <string.h>
+#include <dlfcn.h>
+int main ( void )
+{
+    dlopen(NULL,0);
+}
+
+XEOF
+log -e "The Test Program $TEMP_C" 
+cat $TEMP_C >> $CONFLOG
+DLLIB="none"
+test_include $CC $TEMP_C "$CFLAGS" $TEMP_X "" "$DLLIBS"
+DLLIB=$TRIAL
+log -e "Set DLLIB=$DLLIB"
+
+if [ -x "$TEMP_X" ]
+then
+    logecho "(OK) with $DLLIB"
+fi
+
+if [ "$DLLIB" == "none" ]
+then
+    logecho "fail. We were not able to determine how to use dlopen()"
+    BAIL=yes
+fi
+
+LIBLIBS="$LIBLIBS $DLLIB"
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_pthread # {{{
+{
+logecho -en "Checking for libpthread... "
+
+TEMP_C="$C_TEMPDIR/check_pthread.c"
+TEMP_X=`mktemp $C_TEMPDIR/check_pthread.XXXXXX`
+
+cat > $TEMP_C <<XEOF
+#include <pthread.h>
+int main ( void )
+{
+    pthread_self();
+}
+
+XEOF
+log -e "The Test Program $TEMP_C" 
+cat $TEMP_C >> $CONFLOG
+TLIB="none"
+test_include $CC $TEMP_C "$CFLAGS" $TEMP_X "" "$THREADLIBS"
+TLIB=$TRIAL
+log -e "Set TLIB=$TLIB"
+
+if [ -x "$TEMP_X" ]
+then
+    logecho "(OK) with $TLIB"
+fi
+
+if [ "$TLIB" == "none" ]
+then
+    logecho "fail. We were not able to determine how to use POSIX Threads"
+    BAIL=yes
+fi
+
+LIBLIBS="$LIBLIBS $TLIB"
+
+rm -f $TEMP_C
+rm -f $TEMP_X
+
+} #}}}
+
+function check_doxygen #{{{
+{
+    logecho -en "Checking for doxygen ... "
+    DOXYGEN=`which doxygen 2>/dev/null`
+    if [ -z "$DOXYGEN" ]
+    then
+	DOXYGEN="ls"
+	echo "no"
+	BAIL="yes"
+	mkdir -p doc
+	cat > doc/EMPTY <<XEOF
+This file has been generated because of a missing doxygen. This is not
+runtime critical, you just don't have the class devel documentation.
+If you plan to just use the Library, you can ignore this.
+XEOF
+	DOXYGEN="(echo \"Cannot generate doxumentation, doxygen not installed\"; exit 1); echo &>/dev/null "
+    else
+	echo -e "$DOXYGEN (OK)"
+    fi
+    log -e "DOXYGEN=$DOXYGEN"
+    
+} # }}}
+
+function check_libpqxx # {{{
+{
+    WANTED_VER=$1
+logecho -en "Checking for usable libpqxx ... "
+
+if [ "$PKG_CONFIG" ]
+then
+    $PKG_CONFIG --exists libpqxx
+    EXIST=$?
+
+    if [ "$EXIST" == 0 ]
+    then
+	logecho "(OK)"
+    else
+	logecho "failed"
+	logecho "We were not able to locate libpqxx via pkg-config"
+	BAIL=yes
+	return
+    fi
+    PQX_VER=$($PKG_CONFIG --modversion libpqxx)
+else
+    
+TEMP_CPP="$C_TEMPDIR/check_libpq.cpp"
+TEMP_X=`mktemp $C_TEMPDIR/check_libpq.XXXXXX`
+
+cat > $TEMP_CPP <<XEOF
+
+#include <pqxx/pqxx>
+#include <pqxx/compiler.h>
+
+int main ( void )
+{
+    pqxx::connection Conn;
+    int maj, min, rel;
+    printf(VERSION);
+}
+
+XEOF
+log -e "TEst Program $TEMP_CPP"
+cat $TEMP_CPP >> $CONFLOG
+log -e "Exec( $CPP $CPPFLAGS -I $PG_INCLUDE  -lpqxx $TEMP_CPP -o $TEMP_X)"
+$CPP $CPPFLAGS -I $PG_INCLUDE  -lpqxx $TEMP_CPP -o $TEMP_X >> $CONFLOG 2>&1 
+
+if [ ! -x $TEMP_X ]
+then
+    logecho -e "fail"
+    logecho -e "We were not able to generate a check program, please see $CONFLOG for details"
+    BAIL=yes
+    return
+fi
+
+logecho "(OK)"
+
+PQX_VER=`$TEMP_X 2>/dev/null`
+fi
+
+logecho -en "Checking for libpqxx >= $WANTED_VER ... "
+check_version $WANTED_VER $PQX_VER "libpqxx"
+
+if [ "$VERSION_OK" != "yes" ]
+then
+    BAIL=yes
+    return
+fi
+
+
+rm -f $TEMP_CPP
+rm -f $TEMP_X
+
+logecho -e  "$PQX_VER (OK)"
+
+} #}}}
+
+function check_xerces # {{{
+{
+    WANTED_VER=$1
+    CHECKME=xerces
+    logecho -en "Checking for lib$CHECKME ..."
+
+    search_libdir "-lxerces-c" "$XERCESLIBDIRS"
+    logsetvar XERCES_LIBDIR $FOUNDLIB
+
+    if [ -z "$FOUNDLIB" ]
+    then
+	logecho -e "fail"
+	logecho -e "We were not able to generate a check program for $CHECKME."
+        logecho -e "please see $CONFLOG for details"
+	BAIL=yes
+	return
+    fi
+    logecho "(OK)"
+
+    TEMP_CPP="$C_TEMPDIR/check_xerces.cpp"
+    TEMP_X=`mktemp $C_TEMPDIR/check_xerces.XXXXXX`
+
+cat > $TEMP_CPP <<XEOF
+
+#include <xercesc/util/XercesVersion.hpp>
+#include <stdio.h>
+
+int main ( void )
+{
+    printf("%d.%d.%d", XERCES_VERSION_MAJOR, XERCES_VERSION_MINOR, XERCES_VERSION_REVISION);
+    return 0;
+}
+
+XEOF
+
+    logecho -en "Checking for $CHECKME includes ... "
+    test_include $CPP $TEMP_CPP "$CFLAGS" $TEMP_X -I "$XERCESINCDIRS"
+
+    if [ -x $TEMP_X ]
+    then
+	XER_VER=$($TEMP_X)
+	logecho " (OK)"
+    else
+	logecho -e " failed"
+	BAIL=yes
+	return
+    fi
+    logecho -en "Checking for $CHECKME >= $WANTED_VER ... "
+    check_version $WANTED_VER $XER_VER "xerces"
+
+    if [ "$VERSION_OK" != "yes" ]
+    then
+	BAIL=yes
+	return
+    fi
+
+    rm -f $TEMP_CPP
+    rm -f $TEMP_X
+
+    logecho -e  "$XER_VER (OK)"
+
+} #}}}
+
+function check_qt3 # {{{
+{
+    WANTED_VER=$1
+    CHECKME=qt3
+    logecho -en "Checking for lib$CHECKME ..."
+
+    search_libdir "-lqt-mt" "$QT3LIBDIRS"
+    logsetvar QT3_LIBDIR $FOUNDLIB
+
+    if [ -z "$FOUNDLIB" ]
+    then
+	logecho -e "fail"
+	logecho -e "We were not able to generate a check program for $CHECKME."
+        logecho -e "please see $CONFLOG for details"
+	BAIL=yes
+	return
+    fi
+    logecho "(OK)"
+
+    TEMP_CPP="$C_TEMPDIR/check_qt3.cpp"
+    TEMP_X=`mktemp $C_TEMPDIR/check_qt3.XXXXXX`
+
+cat > $TEMP_CPP <<XEOF
+
+#include <qglobal.h>
+#include <stdio.h>
+
+int main ( void )
+{
+    printf(QT_VERSION_STR);
+    return 0;
+}
+
+XEOF
+
+    logecho -en "Checking for $CHECKME includes ... "
+    test_include $CPP $TEMP_CPP "$CFLAGS" $TEMP_X -I "$QT3INCDIRS"
+    logsetvar QT3_INCLUDE $TRIAL
+
+    if [ -x $TEMP_X ]
+    then
+	QT3_VER=$($TEMP_X)
+	logecho " (OK)"
+    else
+	logecho -e " failed"
+	BAIL=yes
+	return
+    fi
+    logecho -en "Checking for $CHECKME >= $WANTED_VER ... "
+    check_version $WANTED_VER $QT3_VER "qt3"
+
+    if [ "$VERSION_OK" != "yes" ]
+    then
+	BAIL=yes
+	return
+    fi
+
+    rm -f $TEMP_CPP
+    rm -f $TEMP_X
+
+    logecho -e  "$QT3_VER (OK)"
+
+    QT3_BINDIR=$(echo -n $QT3_LIBDIR |  sed 's/lib\/$/bin\//')
+    logecho -en "Checking for moc compiler in $QT3_BINDIR ... "
+    if [ -x $QT3_BINDIR/moc ]
+    then
+	MOC=$QT3_BINDIR/moc
+	logecho -e "($MOC)"
+    else
+	BAIL=yes
+	return
+    fi
+} #}}}
+
+function set_incdir #{{{
+{
+    INCDIR=$1
+    if [ ! -z "$INCDIR" ]
+    then
+	echo "INCLUDES:=\$(INCLUDES) -I $INCDIR" >> $MAKEFILE
+    fi
+} #}}}
+
+function set_libdir #{{{
+{
+    LIBDIR=$1
+    if [ ! -z "$LIBDIR" ]
+    then
+	echo "LIBSEARCH:=\$(LIBSEARCH) -L $LIBDIR" >> $MAKEFILE
+    fi
+} #}}}
+
+function check_echo # {{{
+{
+    logecho -en "Checking how to invoke echo in make ... "
+
+    OUTPUT=`echo -en`
+    if [ -z "$OUTPUT" ]
+    then
+	logecho " with -en"
+	ECHOEN="echo -en"
+    else
+	logecho " plain"
+	ECHOEN="echo"
+    fi
+    
+} # }}}
+# This generates the makefile from all the set variables
+function gen_makefile # {{{
+{
+    if [ ! -z "$C_TEMPDIR" ]
+    then
+	rm -rf $C_TEMPDIR
+    fi
+    MAKEFILE=$1
+
+    logecho -e "Generating $MAKEFILE"
+
+    cat > $MAKEFILE <<XEOF
+############################################################################
+# 
+# DO NOT EDIT THIS FILE !
+# This file is autmagically generated by the iwear configure script suite
+#
+############################################################################
+XEOF
+
+# Checking for CFLAGS or CPPFLAGS overrides
+
+if [ ! -z "$CFLAGS" ]
+then
+    echo -e "Overriding \$CFLAGS to \"$CFLAGS\""
+    echo -e "\nCFLAGS=$CFLAGS" >> $MAKEFILE
+fi
+
+if [ ! -z "$CPPFLAGS" ]
+then
+    echo -e "Overriding \$CPPFLAGS to \"$CPPFLAGS\""
+    echo -e "\nCPPFLAGS=$CPPFLAGS" >> $MAKEFILE
+fi
+echo -e "\nCC=$CC" >> $MAKEFILE
+echo -e "CPP=$CPP" >> $MAKEFILE
+echo -e "\nLIBNAME=$LIBNAME" >> $MAKEFILE
+echo -e "LIBVERSION=$VERSION" >> $MAKEFILE
+echo -e "PREFIX=$PREFIX" >> $MAKEFILE
+echo -e "SYSCONF=$SYSCONF" >> $MAKEFILE
+echo -e "LIBS=$LIBS" >> $MAKEFILE
+echo -e "LIBLIBS=$LIBLIBS" >> $MAKEFILE
+echo -e "INCLUDES=$INCLUDES" >> $MAKEFILE
+echo -e "EXTRACLEANFILES=$EXTRACLEANFILES" >> $MAKEFILE
+echo -e "STERILFILES=$STERILFILES" >> $MAKEFILE
+echo -e "STERILDIRS=$STERILDIRS" >> $MAKEFILE
+echo -e "LIBSEARCH=$PREFIX/lib/" >> $MAKEFILE
+echo -e "DISTNAME=$DISTNAME" >> $MAKEFILE
+echo -e "DISTDIR=$DISTDIR" >> $MAKEFILE
+echo -e "DOXYGEN=$DOXYGEN" >> $MAKEFILE
+echo -e "ECHOEN=$ECHOEN" >> $MAKEFILE
+echo -e "DLLIB=$DLLIB" >> $MAKEFILE
+echo -e "DYN_SUFFIX=$DYN_SUFFIX" >> $MAKEFILE
+echo -e "LIBFLAGS=$LIBFLAGS" >> $MAKEFILE
+echo -e "WEXTRA=$WEXTRA" >> $MAKEFILE
+echo -e "CPPFLAGS:=\$(CPPFLAGS) $SYSCPPFLAGS \$(WEXTRA)" >> $MAKEFILE
+echo -e "CFLAGS:=\$(CFLAGS) $SYSCFLAGS \$(WEXTRA)" >> $MAKEFILE
+echo >> $MAKEFILE
+echo -en "SRCDIRS=" >> $MAKEFILE
+for dir in $SRCDIRS
+do
+    echo -en "\$(TOPDIR)/$dir " >> $MAKEFILE
+done
+echo >> $MAKEFILE
+echo >> $MAKEFILE
+
+#MAINSRC=`echo -e $SRDIRS | cut -d" " -f1`
+if [ "$HAVE_STRCASESTR" == "no" ]
+then
+    LIBFILES_src="$LIBFILES_src strcasestr.o"    
+fi
+
+if [ "$HAVE_STRNLEN" == "no" ]
+then
+    LIBFILES_src="$LIBFILES_src strnlen.o"    
+fi
+
+if [ "$HAVE_CLOCK_GETTIME" == "no" ]
+then
+    LIBFILES_src="$LIBFILES_src clock_gettime.o"    
+fi
+
+set_incdir $PG_INCLUDE
+set_incdir $SSL_INCLUDE
+set_incdir $GLIB2_INCLUDE
+set_incdir $ORBITCPP_INCLUDE
+set_incdir $ORBIT2_INCLUDE
+set_incdir $GLIB2_CONFIG
+set_incdir $IWEAR_INCLUDE
+set_incdir $QT3_INCLUDE
+
+set_libdir $GLIB2_LIBDIR
+set_libdir $ORBIT2_LIBDIR
+set_libdir $QT3_LIBDIR
+set_libdir $IWEAR_LIBDIR
+set_libdir $ORBITCPP_LIBDIR
+
+for dir in $SRCDIRS
+do
+    VARNAME="\$LIBFILES_$dir"
+    eval "FILES=$VARNAME"
+#    echo -e "$VARNAME=$FILES" |  sed 's/^\$//' >> $MAKEFILE
+    NVARNAME=$(echo -e "$VARNAME=" |  sed 's/^\$//')
+    echo -en $NVARNAME >> $MAKEFILE
+    for file in $FILES
+    do
+	echo -n $file" " >> $MAKEFILE
+    done
+    echo >> $MAKEFILE
+done
+
+if [ ! -z "$ORBITCPPIDL" ]
+then
+    echo "OIDL2:=$ORBITCPPIDL" >> $MAKEFILE
+fi
+
+if [ ! -z "$MOC" ]
+then
+    echo "MOC=$MOC" >> $MAKEFILE
+fi
+
+
+} # }}}
+
+# This generates the config.h header
+function gen_config # {{{
+{
+    CONFIG_H=$1
+    log -e "Generating $CONFIG_H"
+cat > $CONFIG_H <<EOF
+/**
+* @file This file is automagically generated by configure.
+*
+* It should contain parameters that will be compiled in, but are changable at
+* compile time. Also constants choosing different behaviour may be listed
+* here.
+*/
+EOF
+
+GPREFIX=$(echo $DISTNAME | toupper | sed 's/-/_/g')
+
+# Begin with the global section. Those are generally overridden by projects config.h
+
+echo -e "#ifndef __CONFIG_H" >> $CONFIG_H
+echo -e "#define __CONFIG_H" >> $CONFIG_H
+
+echo -e "\n#define PREFIX \"$PREFIX\"" >> $CONFIG_H
+echo -e "\n#define DYN_SUFFIX \"$DYN_SUFFIX\"" >> $CONFIG_H
+echo -e "\n#define SYSCONF \"$SYSCONF\"" >> $CONFIG_H
+echo -e "#define ARCH \"$CPU\"" >> $CONFIG_H
+
+# TODO We need to really check for gnu compatible environment
+echo -e "\n#ifndef _GNU_SOURCE" >> $CONFIG_H
+echo -e "#define _GNU_SOURCE" >> $CONFIG_H
+echo -e "#endif\n" >> $CONFIG_H
+
+echo -e "#endif\n\n" >> $CONFIG_H
+
+#
+# End global config.h ... the next is specific to iwear headers, and therefore should only origin there
+
+echo -e "#ifndef __${GPREFIX}_CONFIG_H" >> $CONFIG_H
+echo -e "#define __${GPREFIX}_CONFIG_H" >> $CONFIG_H
+
+if [ "$SSL_INCLUDE" ]
+then
+    echo -e "\n#undef SSL_INCLUDE" >> $CONFIG_H
+    echo -e "#define SSL_INCLUDE $SSL_INCLUDE" >> $CONFIG_H
+    echo -e "#define SSINC(x) <SSL_INCLUDE/x>" >> $CONFIG_H
+    echo -e "#ifndef OPENSSL_NO_KRB5" >> $CONFIG_H
+    echo -e "#define OPENSSL_NO_KRB5" >> $CONFIG_H
+    echo -e "#endif " >> $CONFIG_H
+fi
+
+if [ "$HAVE_STRNLEN" == "yes" ]
+then
+    echo -e "\n#undef HAVE_STRNLEN" >> $CONFIG_H
+    echo -e "#define HAVE_STRNLEN 1" >> $CONFIG_H
+fi
+
+if [ "$HAVE_STRCASESTR" == "yes" ]
+then
+    echo -e "\n#undef HAVE_STRCASESTR" >> $CONFIG_H
+    echo -e "#define HAVE_STRCASESTR 1" >> $CONFIG_H
+fi
+
+if [ "$HAVE_VASPRINTF" == "yes" ]
+then
+    echo -e "\n#undef HAVE_VASPRINTF" >> $CONFIG_H
+    echo -e "#define HAVE_VASPRINTF 1" >> $CONFIG_H
+fi
+
+if [ "$HAVE_STRERROR_R" == "yes" ]
+then
+    echo -e "\n#undef HAVE_STRERROR_R" >> $CONFIG_H
+    echo -e "#define HAVE_STRERROR_R 1" >> $CONFIG_H
+fi
+
+if [ "$HAVE_CLOCK_GETTIME" == "yes" ]
+then
+    echo -e "\n#undef HAVE_CLOCK_GETTIME" >> $CONFIG_H
+    echo -e "#define HAVE_CLOCK_GETTIME 1" >> $CONFIG_H
+fi
+
+if [ $OS_TYPE == "mac" ]
+then
+    echo -e "\n#undef IW_MAC" >> $CONFIG_H
+    echo -e "#define IW_MAC 1" >> $CONFIG_H
+fi
+
+if [ $OS_TYPE == "solaris" ]
+then
+    echo -e "\n#undef IW_SOLARIS" >> $CONFIG_H
+    echo -e "#define IW_SOLARIS 1" >> $CONFIG_H
+fi
+
+echo -e "\n#endif" >> $CONFIG_H
+VPREF=`echo -e $DISTNAME | toupper | sed 's/-/_/g'`
+
+if [ ! -z "$PG_INCLUDE" ]
+then
+    echo -e "#define HAVE_IWPGDB 1" >> $CONFIG_H
+fi
+
+read V_MAJOR V_MINOR V_RELEASE < <(echo $VERSION | sed 's/\./ /g');
+echo -e "\n#ifndef ${VPREF}_MAJOR" >> $CONFIG_H
+echo -e "#define ${VPREF}_MAJOR $V_MAJOR" >> $CONFIG_H
+echo -e "#define ${VPREF}_MINOR $V_MINOR" >> $CONFIG_H
+echo -e "#define ${VPREF}_RELEASE $V_RELEASE" >> $CONFIG_H
+echo -e "#endif" >> $CONFIG_H
+} # }}} 
+
Index: /tags/help/iwearrpc/Makefile
===================================================================
--- /tags/help/iwearrpc/Makefile (revision 2229)
+++ /tags/help/iwearrpc/Makefile (revision 2229)
@@ -0,0 +1,37 @@
+# 
+# This is a basic makefile that uses a flat directory structure. It could be
+# expanded to support multiple subdirectories and/or libraries
+#
+
+#.SILENT: all lib test steril clean tar dist link .DEFAULT
+TOPDIR=.
+
+ROOTDIR=true
+SUBLIBFILES=$(LIBFILES_$(PWD))
+TRANSDIR=./share/locale/
+TRANSTEMPLATE=iwremote.pot
+
+all:	systarget
+
+include Makefile.common
+
+systarget: lib
+
+testclient: lib testclient.o testcommon.o
+	@echo $(VIO)[MAKE]$(NOR) $@
+	@$(MAKE) -C src $@
+
+testserver: lib testserver.o testcommon.o
+	@echo $(VIO)[MAKE]$(NOR) $@
+	@$(MAKE) -C src $@
+
+rpctest test poread:	lib
+	@echo $(VIO)[MAKE]$(NOR) $@
+	@$(MAKE) -C src $@
+
+remotetest: lib testserver.o testcommon.o testclient.o ./src/remotetest.o
+	@echo $(VIO)[MAKE]$(NOR) $@
+	@$(MAKE) -C src $@
+
+parser/idlparse.cc: parser/idlparse.tab.hh parser/idlparse.lex
+parser/idlparse.tab.h: parser/idlparse.y	
