You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2017/11/21 20:07:58 UTC

[01/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Repository: celix
Updated Branches:
  refs/heads/feature/CELIX-417-cmake-refactor a1c308879 -> 2a670f265


http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/utils/private/src/md5.inl
----------------------------------------------------------------------
diff --git a/remote_services/utils/private/src/md5.inl b/remote_services/utils/private/src/md5.inl
deleted file mode 100644
index 4da933d..0000000
--- a/remote_services/utils/private/src/md5.inl
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * This an amalgamation of md5.c and md5.h into a single file
- * with all static declaration to reduce linker conflicts
- * in Civetweb.
- *
- * The MD5_STATIC declaration was added to facilitate static
- * inclusion.
- * No Face Press, LLC
- */
-
-/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321, whose
-  text is available at
-	http://www.ietf.org/rfc/rfc1321.txt
-  The code is derived from the text of the RFC, including the test suite
-  (section A.5) but excluding the rest of Appendix A.  It does not include
-  any code or documentation that is identified in the RFC as being
-  copyrighted.
-
-  The original and principal author of md5.h is L. Peter Deutsch
-  <gh...@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  2002-04-13 lpd Removed support for non-ANSI compilers; removed
-	references to Ghostscript; clarified derivation from RFC 1321;
-	now handles byte order either statically or dynamically.
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
-	added conditionalization for C++ compilation from Martin
-	Purschke <pu...@bnl.gov>.
-  1999-05-03 lpd Original version.
- */
-
-#ifndef md5_INCLUDED
-#  define md5_INCLUDED
-
-/*
- * This package supports both compile-time and run-time determination of CPU
- * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
- * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
- * defined as non-zero, the code will be compiled to run only on big-endian
- * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
- * run on either big- or little-endian CPUs, but will run slightly less
- * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
- */
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
-    md5_word_t count[2];	/* message length in bits, lsw first */
-    md5_word_t abcd[4];		/* digest buffer */
-    md5_byte_t buf[64];		/* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/* Initialize the algorithm. */
-MD5_STATIC void md5_init(md5_state_t *pms);
-
-/* Append a string to the message. */
-MD5_STATIC void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-
-/* Finish the message and return the digest. */
-MD5_STATIC void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-
-#ifdef __cplusplus
-}  /* end extern "C" */
-#endif
-
-#endif /* md5_INCLUDED */
-
-/*
-  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321, whose
-  text is available at
-	http://www.ietf.org/rfc/rfc1321.txt
-  The code is derived from the text of the RFC, including the test suite
-  (section A.5) but excluding the rest of Appendix A.  It does not include
-  any code or documentation that is identified in the RFC as being
-  copyrighted.
-
-  The original and principal author of md5.c is L. Peter Deutsch
-  <gh...@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
-	either statically or dynamically; added missing #include <string.h>
-	in library.
-  2002-03-11 lpd Corrected argument list for main(), and added int return
-	type, in test program and T value program.
-  2002-02-21 lpd Added missing #include <stdio.h> in test program.
-  2000-07-03 lpd Patched to eliminate warnings about "constant is
-	unsigned in ANSI C, signed in traditional"; made test program
-	self-checking.
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
-  1999-05-03 lpd Original version.
- */
-
-#ifndef MD5_STATIC
-#include <string.h>
-#endif
-
-#undef BYTE_ORDER	/* 1 = big-endian, -1 = little-endian, 0 = unknown */
-#ifdef ARCH_IS_BIG_ENDIAN
-#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
-#else
-#  define BYTE_ORDER 0
-#endif
-
-#define T_MASK ((md5_word_t)~0)
-#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
-#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
-#define T3    0x242070db
-#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
-#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
-#define T6    0x4787c62a
-#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
-#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
-#define T9    0x698098d8
-#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
-#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
-#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
-#define T13    0x6b901122
-#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
-#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
-#define T16    0x49b40821
-#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
-#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
-#define T19    0x265e5a51
-#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
-#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
-#define T22    0x02441453
-#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
-#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
-#define T25    0x21e1cde6
-#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
-#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
-#define T28    0x455a14ed
-#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
-#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
-#define T31    0x676f02d9
-#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
-#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
-#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
-#define T35    0x6d9d6122
-#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
-#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
-#define T38    0x4bdecfa9
-#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
-#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
-#define T41    0x289b7ec6
-#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
-#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
-#define T44    0x04881d05
-#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
-#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
-#define T47    0x1fa27cf8
-#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
-#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
-#define T50    0x432aff97
-#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
-#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
-#define T53    0x655b59c3
-#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
-#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
-#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
-#define T57    0x6fa87e4f
-#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
-#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
-#define T60    0x4e0811a1
-#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
-#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
-#define T63    0x2ad7d2bb
-#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
-
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
-    md5_word_t
-    a = pms->abcd[0], b = pms->abcd[1],
-    c = pms->abcd[2], d = pms->abcd[3];
-    md5_word_t t;
-#if BYTE_ORDER > 0
-    /* Define storage only for big-endian CPUs. */
-    md5_word_t X[16];
-#else
-    /* Define storage for little-endian or both types of CPUs. */
-    md5_word_t xbuf[16];
-    const md5_word_t *X;
-#endif
-
-    {
-#if BYTE_ORDER == 0
-        /*
-         * Determine dynamically whether this is a big-endian or
-         * little-endian machine, since we can use a more efficient
-         * algorithm on the latter.
-         */
-        static const int w = 1;
-
-        if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
-#endif
-#if BYTE_ORDER <= 0		/* little-endian */
-        {
-            /*
-             * On little-endian machines, we can process properly aligned
-             * data without copying it.
-             */
-            if (!((data - (const md5_byte_t *)0) & 3)) {
-                /* data are properly aligned */
-                X = (const md5_word_t *)data;
-            } else {
-                /* not aligned */
-                memcpy(xbuf, data, 64);
-                X = xbuf;
-            }
-        }
-#endif
-#if BYTE_ORDER == 0
-        else			/* dynamic big-endian */
-#endif
-#if BYTE_ORDER >= 0		/* big-endian */
-        {
-            /*
-             * On big-endian machines, we must arrange the bytes in the
-             * right order.
-             */
-            const md5_byte_t *xp = data;
-            int i;
-
-#  if BYTE_ORDER == 0
-            X = xbuf;		/* (dynamic only) */
-#  else
-#    define xbuf X		/* (static only) */
-#  endif
-            for (i = 0; i < 16; ++i, xp += 4)
-                xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
-        }
-#endif
-    }
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
-    /* Round 1. */
-    /* Let [abcd k s i] denote the operation
-       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + F(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-    /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  7,  T1);
-    SET(d, a, b, c,  1, 12,  T2);
-    SET(c, d, a, b,  2, 17,  T3);
-    SET(b, c, d, a,  3, 22,  T4);
-    SET(a, b, c, d,  4,  7,  T5);
-    SET(d, a, b, c,  5, 12,  T6);
-    SET(c, d, a, b,  6, 17,  T7);
-    SET(b, c, d, a,  7, 22,  T8);
-    SET(a, b, c, d,  8,  7,  T9);
-    SET(d, a, b, c,  9, 12, T10);
-    SET(c, d, a, b, 10, 17, T11);
-    SET(b, c, d, a, 11, 22, T12);
-    SET(a, b, c, d, 12,  7, T13);
-    SET(d, a, b, c, 13, 12, T14);
-    SET(c, d, a, b, 14, 17, T15);
-    SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
-    /* Round 2. */
-    /* Let [abcd k s i] denote the operation
-         a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + G(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-    /* Do the following 16 operations. */
-    SET(a, b, c, d,  1,  5, T17);
-    SET(d, a, b, c,  6,  9, T18);
-    SET(c, d, a, b, 11, 14, T19);
-    SET(b, c, d, a,  0, 20, T20);
-    SET(a, b, c, d,  5,  5, T21);
-    SET(d, a, b, c, 10,  9, T22);
-    SET(c, d, a, b, 15, 14, T23);
-    SET(b, c, d, a,  4, 20, T24);
-    SET(a, b, c, d,  9,  5, T25);
-    SET(d, a, b, c, 14,  9, T26);
-    SET(c, d, a, b,  3, 14, T27);
-    SET(b, c, d, a,  8, 20, T28);
-    SET(a, b, c, d, 13,  5, T29);
-    SET(d, a, b, c,  2,  9, T30);
-    SET(c, d, a, b,  7, 14, T31);
-    SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
-    /* Round 3. */
-    /* Let [abcd k s t] denote the operation
-         a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + H(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-    /* Do the following 16 operations. */
-    SET(a, b, c, d,  5,  4, T33);
-    SET(d, a, b, c,  8, 11, T34);
-    SET(c, d, a, b, 11, 16, T35);
-    SET(b, c, d, a, 14, 23, T36);
-    SET(a, b, c, d,  1,  4, T37);
-    SET(d, a, b, c,  4, 11, T38);
-    SET(c, d, a, b,  7, 16, T39);
-    SET(b, c, d, a, 10, 23, T40);
-    SET(a, b, c, d, 13,  4, T41);
-    SET(d, a, b, c,  0, 11, T42);
-    SET(c, d, a, b,  3, 16, T43);
-    SET(b, c, d, a,  6, 23, T44);
-    SET(a, b, c, d,  9,  4, T45);
-    SET(d, a, b, c, 12, 11, T46);
-    SET(c, d, a, b, 15, 16, T47);
-    SET(b, c, d, a,  2, 23, T48);
-#undef SET
-
-    /* Round 4. */
-    /* Let [abcd k s t] denote the operation
-         a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + I(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-    /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  6, T49);
-    SET(d, a, b, c,  7, 10, T50);
-    SET(c, d, a, b, 14, 15, T51);
-    SET(b, c, d, a,  5, 21, T52);
-    SET(a, b, c, d, 12,  6, T53);
-    SET(d, a, b, c,  3, 10, T54);
-    SET(c, d, a, b, 10, 15, T55);
-    SET(b, c, d, a,  1, 21, T56);
-    SET(a, b, c, d,  8,  6, T57);
-    SET(d, a, b, c, 15, 10, T58);
-    SET(c, d, a, b,  6, 15, T59);
-    SET(b, c, d, a, 13, 21, T60);
-    SET(a, b, c, d,  4,  6, T61);
-    SET(d, a, b, c, 11, 10, T62);
-    SET(c, d, a, b,  2, 15, T63);
-    SET(b, c, d, a,  9, 21, T64);
-#undef SET
-
-    /* Then perform the following additions. (That is increment each
-       of the four registers by the value it had before this block
-       was started.) */
-    pms->abcd[0] += a;
-    pms->abcd[1] += b;
-    pms->abcd[2] += c;
-    pms->abcd[3] += d;
-}
-
-MD5_STATIC void
-md5_init(md5_state_t *pms)
-{
-    pms->count[0] = pms->count[1] = 0;
-    pms->abcd[0] = 0x67452301;
-    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
-    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
-    pms->abcd[3] = 0x10325476;
-}
-
-MD5_STATIC void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
-    const md5_byte_t *p = data;
-    int left = nbytes;
-    int offset = (pms->count[0] >> 3) & 63;
-    md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
-    if (nbytes <= 0)
-        return;
-
-    /* Update the message length. */
-    pms->count[1] += nbytes >> 29;
-    pms->count[0] += nbits;
-    if (pms->count[0] < nbits)
-        pms->count[1]++;
-
-    /* Process an initial partial block. */
-    if (offset) {
-        int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
-        memcpy(pms->buf + offset, p, copy);
-        if (offset + copy < 64)
-            return;
-        p += copy;
-        left -= copy;
-        md5_process(pms, pms->buf);
-    }
-
-    /* Process full blocks. */
-    for (; left >= 64; p += 64, left -= 64)
-        md5_process(pms, p);
-
-    /* Process a final partial block. */
-    if (left)
-        memcpy(pms->buf, p, left);
-}
-
-MD5_STATIC void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
-    static const md5_byte_t pad[64] = {
-        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    md5_byte_t data[8];
-    int i;
-
-    /* Save the length before padding. */
-    for (i = 0; i < 8; ++i)
-        data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
-    /* Pad to 56 bytes mod 64. */
-    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
-    /* Append the length. */
-    md5_append(pms, data, 8);
-    for (i = 0; i < 16; ++i)
-        digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/shell/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt
index 31822c4..ae8cf3f 100644
--- a/shell/CMakeLists.txt
+++ b/shell/CMakeLists.txt
@@ -39,7 +39,7 @@ if (SHELL)
           src/help_command
 	)
 	target_include_directories(shell PRIVATE src ${CURL_INCLUDE_DIRS})
-	target_link_libraries(shell PRIVATE Celix::shell_api ${CURL_LIBRARIES} Celix::log_service_api log_helper)
+	target_link_libraries(shell PRIVATE Celix::shell_api ${CURL_LIBRARIES} Celix::log_service_api Celix::log_helper)
 
 	install_bundle(shell
     	HEADERS

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/shell/README.md
----------------------------------------------------------------------
diff --git a/shell/README.md b/shell/README.md
index 76f1cc7..a20450c 100644
--- a/shell/README.md
+++ b/shell/README.md
@@ -30,4 +30,5 @@ ANSI colors when printing info. default is true.
 ## Using info
 
 If the Celix Shell is installed The `FindCelix.cmake` will set:
- - The `Celix::dependency_manager_cxx_static` library target
+ - The `Celix::shell_api` interface (i.e. header only) library target
+ - The `Celix::shell` bundle target


[06/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
deleted file mode 100644
index 9feab9f..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_impl.c
- *
- *  \date       May 21, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <ifaddrs.h>
-#include <string.h>
-#include <uuid/uuid.h>
-#include <curl/curl.h>
-
-#include <jansson.h>
-#include "json_serializer.h"
-#include "remote_service_admin.h"
-#include "celix_threads.h"
-#include "hash_map.h"
-#include "array_list.h"
-
-#include "import_registration_dfi.h"
-#include "export_registration_dfi.h"
-#include "remote_service_admin_dfi.h"
-#include "dyn_interface.h"
-#include "json_rpc.h"
-
-#include "remote_constants.h"
-#include "constants.h"
-#include "civetweb.h"
-
-// defines how often the webserver is restarted (with an increased port number)
-#define MAX_NUMBER_OF_RESTARTS 	5
-
-
-#define RSA_LOG_ERROR(admin, msg, ...) \
-    logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg),  ##__VA_ARGS__)
-
-#define RSA_LOG_WARNING(admin, msg, ...) \
-    logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg),  ##__VA_ARGS__)
-
-#define RSA_LOG_DEBUG(admin, msg, ...) \
-    logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg),  ##__VA_ARGS__)
-
-struct remote_service_admin {
-    bundle_context_pt context;
-    log_helper_pt loghelper;
-
-    celix_thread_mutex_t exportedServicesLock;
-    hash_map_pt exportedServices;
-
-    celix_thread_mutex_t importedServicesLock;
-    array_list_pt importedServices;
-
-    char *port;
-    char *ip;
-
-    struct mg_context *ctx;
-};
-
-struct post {
-    const char *readptr;
-    int size;
-};
-
-struct get {
-    char *writeptr;
-    int size;
-};
-
-#define OSGI_RSA_REMOTE_PROXY_FACTORY 	"remote_proxy_factory"
-#define OSGI_RSA_REMOTE_PROXY_TIMEOUT   "remote_proxy_timeout"
-
-static const char *data_response_headers =
-        "HTTP/1.1 200 OK\r\n"
-                "Cache: no-cache\r\n"
-                "Content-Type: application/json\r\n"
-                "\r\n";
-
-static const char *no_content_response_headers =
-        "HTTP/1.1 204 OK\r\n";
-
-// TODO do we need to specify a non-Amdatu specific configuration type?!
-static const char * const CONFIGURATION_TYPE = "org.amdatu.remote.admin.http";
-static const char * const ENDPOINT_URL = "org.amdatu.remote.admin.http.url";
-
-static const char *DEFAULT_PORT = "8888";
-static const char *DEFAULT_IP = "127.0.0.1";
-
-static const unsigned int DEFAULT_TIMEOUT = 0;
-
-static int remoteServiceAdmin_callback(struct mg_connection *conn);
-static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, char *interface, endpoint_description_pt *description);
-static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
-static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip);
-static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp);
-static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp);
-static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...);
-
-celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    *admin = calloc(1, sizeof(**admin));
-
-    if (!*admin) {
-        status = CELIX_ENOMEM;
-    } else {
-        unsigned int port_counter = 0;
-        const char *port = NULL;
-        const char *ip = NULL;
-        char *detectedIp = NULL;
-        (*admin)->context = context;
-        (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
-         arrayList_create(&(*admin)->importedServices);
-
-        celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
-        celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
-
-        if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
-            logHelper_start((*admin)->loghelper);
-            dynCommon_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
-            dynType_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
-            dynFunction_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
-            dynInterface_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
-            jsonSerializer_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
-            jsonRpc_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
-        }
-
-        bundleContext_getProperty(context, "RSA_PORT", &port);
-        if (port == NULL) {
-            port = (char *)DEFAULT_PORT;
-        }
-
-        bundleContext_getProperty(context, "RSA_IP", &ip);
-        if (ip == NULL) {
-            const char *interface = NULL;
-
-            bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
-            if ((interface != NULL) && (remoteServiceAdmin_getIpAdress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
-                logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Could not retrieve IP adress for interface %s", interface);
-            }
-
-            if (ip == NULL) {
-                remoteServiceAdmin_getIpAdress(NULL, &detectedIp);
-            }
-
-            ip = detectedIp;
-        }
-
-        if (ip != NULL) {
-            logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Using %s for service annunciation", ip);
-            (*admin)->ip = strdup(ip);
-        }
-        else {
-            logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No IP address for service annunciation set. Using %s", DEFAULT_IP);
-            (*admin)->ip = strdup((char*) DEFAULT_IP);
-        }
-
-        if (detectedIp != NULL) {
-            free(detectedIp);
-        }
-
-        // Prepare callbacks structure. We have only one callback, the rest are NULL.
-        struct mg_callbacks callbacks;
-        memset(&callbacks, 0, sizeof(callbacks));
-        callbacks.begin_request = remoteServiceAdmin_callback;
-
-        char newPort[10];
-
-        do {
-
-            const char *options[] = { "listening_ports", port, "num_threads", "5", NULL};
-
-            (*admin)->ctx = mg_start(&callbacks, (*admin), options);
-
-            if ((*admin)->ctx != NULL) {
-                logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Start webserver: %s", port);
-                (*admin)->port = strdup(port);
-
-            }
-            else {
-            	errno = 0;
-                char* endptr = (char*)port;
-                int currentPort = strtol(port, &endptr, 10);
-
-                if (*endptr || errno != 0) {
-                    currentPort = strtol(DEFAULT_PORT, NULL, 10);
-                }
-
-                port_counter++;
-                snprintf(&newPort[0], 6,  "%d", (currentPort+1));
-
-                logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting rsa server on port %s - retrying on port %s...", port, newPort);
-                port = newPort;
-            }
-        } while(((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS));
-
-    }
-
-    return status;
-}
-
-
-celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin)
-{
-    celix_status_t status = CELIX_SUCCESS;
-
-    free((*admin)->ip);
-    free((*admin)->port);
-    free(*admin);
-
-    //TODO destroy exports/imports
-
-    *admin = NULL;
-
-    return status;
-}
-
-
-celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    celixThreadMutex_lock(&admin->exportedServicesLock);
-
-    hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
-    while (hashMapIterator_hasNext(iter)) {
-        array_list_pt exports = hashMapIterator_nextValue(iter);
-        int i;
-        for (i = 0; i < arrayList_size(exports); i++) {
-            export_registration_pt export = arrayList_get(exports, i);
-            if (export != NULL) {
-                exportRegistration_stop(export);
-                exportRegistration_destroy(export);
-            }
-        }
-        arrayList_destroy(exports);
-    }
-    hashMapIterator_destroy(iter);
-    celixThreadMutex_unlock(&admin->exportedServicesLock);
-
-    celixThreadMutex_lock(&admin->importedServicesLock);
-    int i;
-    int size = arrayList_size(admin->importedServices);
-    for (i = 0; i < size ; i += 1) {
-        import_registration_pt import = arrayList_get(admin->importedServices, i);
-        if (import != NULL) {
-            importRegistration_stop(import);
-            importRegistration_destroy(import);
-        }
-    }
-    celixThreadMutex_unlock(&admin->importedServicesLock);
-
-    if (admin->ctx != NULL) {
-        logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Stopping webserver...");
-        mg_stop(admin->ctx);
-        admin->ctx = NULL;
-    }
-
-    hashMap_destroy(admin->exportedServices, false, false);
-    arrayList_destroy(admin->importedServices);
-
-    logHelper_stop(admin->loghelper);
-    logHelper_destroy(&admin->loghelper);
-
-    return status;
-}
-
-/**
- * Request: http://host:port/services/{service}/{request}
- */
-//void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) {
-
-celix_status_t importRegistration_getFactory(import_registration_pt import, service_factory_pt *factory);
-
-static int remoteServiceAdmin_callback(struct mg_connection *conn) {
-    int result = 1; // zero means: let civetweb handle it further, any non-zero value means it is handled by us...
-
-    const struct mg_request_info *request_info = mg_get_request_info(conn);
-    if (request_info->uri != NULL) {
-        remote_service_admin_pt rsa = request_info->user_data;
-
-
-        if (strncmp(request_info->uri, "/service/", 9) == 0 && strcmp("POST", request_info->request_method) == 0) {
-
-            // uri = /services/myservice/call
-            const char *uri = request_info->uri;
-            // rest = myservice/call
-
-            const char *rest = uri+9;
-            char *interfaceStart = strchr(rest, '/');
-            int pos = interfaceStart - rest;
-            char service[pos+1];
-            strncpy(service, rest, pos);
-            service[pos] = '\0';
-            unsigned long serviceId = strtoul(service,NULL,10);
-
-            celixThreadMutex_lock(&rsa->exportedServicesLock);
-
-            //find endpoint
-            export_registration_pt export = NULL;
-            hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
-            while (hashMapIterator_hasNext(iter)) {
-                hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-                array_list_pt exports = hashMapEntry_getValue(entry);
-                int expIt = 0;
-                for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
-                    export_registration_pt check = arrayList_get(exports, expIt);
-                    export_reference_pt  ref = NULL;
-                    exportRegistration_getExportReference(check, &ref);
-                    endpoint_description_pt  checkEndpoint = NULL;
-                    exportReference_getExportedEndpoint(ref, &checkEndpoint);
-                    if (serviceId == checkEndpoint->serviceId) {
-                        export = check;
-                        free(ref);
-                        break;
-                    }
-                    free(ref);
-                }
-            }
-            hashMapIterator_destroy(iter);
-
-            if (export != NULL) {
-
-                uint64_t datalength = request_info->content_length;
-                char* data = malloc(datalength + 1);
-                mg_read(conn, data, datalength);
-                data[datalength] = '\0';
-
-                char *response = NULL;
-                int responceLength = 0;
-                int rc = exportRegistration_call(export, data, -1, &response, &responceLength);
-                if (rc != CELIX_SUCCESS) {
-                    RSA_LOG_ERROR(rsa, "Error trying to invoke remove service, got error %i\n", rc);
-                }
-
-                if (rc == CELIX_SUCCESS && response != NULL) {
-                    mg_write(conn, data_response_headers, strlen(data_response_headers));
-                    mg_write(conn, response, strlen(response));
-                    free(response);
-                } else {
-                    mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
-                }
-                result = 1;
-
-                free(data);
-            } else {
-                result = 0;
-                RSA_LOG_WARNING(rsa, "NO export registration found for service id %lu", serviceId);
-            }
-
-            celixThreadMutex_unlock(&rsa->exportedServicesLock);
-
-        }
-    }
-
-    return result;
-}
-
-celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
-    celix_status_t status;
-
-    arrayList_create(registrations);
-    array_list_pt references = NULL;
-    service_reference_pt reference = NULL;
-    char filter [256];
-
-    snprintf(filter, 256, "(%s=%s)", (char *)OSGI_FRAMEWORK_SERVICE_ID, serviceId);
-
-    status = bundleContext_getServiceReferences(admin->context, NULL, filter, &references);
-
-    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId);
-
-    int i;
-    int size = arrayList_size(references);
-    for (i = 0; i < size; i += 1) {
-        if (i == 0) {
-            reference = arrayList_get(references, i);
-        } else {
-            bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i));
-        }
-    }
-    arrayList_destroy(references);
-
-    if (reference == NULL) {
-        logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
-        status = CELIX_ILLEGAL_STATE;
-    }
-
-    const char *exports = NULL;
-    const char *provided = NULL;
-    if (status == CELIX_SUCCESS) {
-        serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
-        serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
-
-        if (exports == NULL || provided == NULL || strcmp(exports, provided) != 0) {
-            logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
-            status = CELIX_ILLEGAL_STATE;
-        } else {
-            logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
-        }
-    }
-
-    if (status == CELIX_SUCCESS) {
-        const char *interface = provided;
-        endpoint_description_pt endpoint = NULL;
-        export_registration_pt registration = NULL;
-
-        remoteServiceAdmin_createEndpointDescription(admin, reference, properties, (char*)interface, &endpoint);
-        //TODO precheck if descriptor exists
-        status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, &registration);
-        if (status == CELIX_SUCCESS) {
-            status = exportRegistration_start(registration);
-            if (status == CELIX_SUCCESS) {
-                arrayList_add(*registrations, registration);
-            }
-        }
-    }
-
-
-    if (status == CELIX_SUCCESS) {
-        celixThreadMutex_lock(&admin->exportedServicesLock);
-        hashMap_put(admin->exportedServices, reference, *registrations);
-        celixThreadMutex_unlock(&admin->exportedServicesLock);
-    }
-    else{
-    	arrayList_destroy(*registrations);
-    	*registrations = NULL;
-    }
-
-    return status;
-}
-
-celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration) {
-    celix_status_t status;
-
-    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing exported service");
-
-    export_reference_pt  ref = NULL;
-    status = exportRegistration_getExportReference(registration, &ref);
-
-    if (status == CELIX_SUCCESS && ref != NULL) {
-    	service_reference_pt servRef;
-        celixThreadMutex_lock(&admin->exportedServicesLock);
-    	exportReference_getExportedService(ref, &servRef);
-
-    	array_list_pt exports = (array_list_pt)hashMap_remove(admin->exportedServices, servRef);
-    	if(exports!=NULL){
-    		arrayList_destroy(exports);
-    	}
-
-        exportRegistration_close(registration);
-        exportRegistration_destroy(registration);
-
-        celixThreadMutex_unlock(&admin->exportedServicesLock);
-
-        free(ref);
-
-    } else {
-    	logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot find reference for registration");
-    }
-
-    return status;
-}
-
-static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, char *interface, endpoint_description_pt *endpoint) {
-
-    celix_status_t status = CELIX_SUCCESS;
-    properties_pt endpointProperties = properties_create();
-
-
-    unsigned int size = 0;
-    char **keys;
-
-    serviceReference_getPropertyKeys(reference, &keys, &size);
-    for (int i = 0; i < size; i++) {
-        char *key = keys[i];
-        const char *value = NULL;
-
-        if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS
-            && strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
-            && strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
-            properties_set(endpointProperties, key, value);
-        }
-    }
-
-    hash_map_entry_pt entry = hashMap_getEntry(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
-
-    char* key = hashMapEntry_getKey(entry);
-    char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
-    const char *uuid = NULL;
-
-    char buf[512];
-    snprintf(buf, 512,  "/service/%s/%s", serviceId, interface);
-
-    char url[1024];
-    snprintf(url, 1024, "http://%s:%s%s", admin->ip, admin->port, buf);
-
-    uuid_t endpoint_uid;
-    uuid_generate(endpoint_uid);
-    char endpoint_uuid[37];
-    uuid_unparse_lower(endpoint_uid, endpoint_uuid);
-
-    bundleContext_getProperty(admin->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-    properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
-    properties_set(endpointProperties, (char*) OSGI_FRAMEWORK_OBJECTCLASS, interface);
-    properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId);
-    properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid);
-    properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true");
-    properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) CONFIGURATION_TYPE);
-    properties_set(endpointProperties, (char*) ENDPOINT_URL, url);
-
-    if (props != NULL) {
-        hash_map_iterator_pt propIter = hashMapIterator_create(props);
-        while (hashMapIterator_hasNext(propIter)) {
-    	    hash_map_entry_pt entry = hashMapIterator_nextEntry(propIter);
-    	    properties_set(endpointProperties, (char*)hashMapEntry_getKey(entry), (char*)hashMapEntry_getValue(entry));
-        }
-        hashMapIterator_destroy(propIter);
-    }
-
-    *endpoint = calloc(1, sizeof(**endpoint));
-    if (!*endpoint) {
-        status = CELIX_ENOMEM;
-    } else {
-        (*endpoint)->id = (char*)properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
-        const char *serviceId = NULL;
-        serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
-        (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
-        (*endpoint)->frameworkUUID = (char*) properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
-        (*endpoint)->service = strndup(interface, 1024*10);
-        (*endpoint)->properties = endpointProperties;
-    }
-
-    free(key);
-    free(serviceId);
-    free(keys);
-
-    return status;
-}
-
-static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip) {
-    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
-    struct ifaddrs *ifaddr, *ifa;
-    char host[NI_MAXHOST];
-
-    if (getifaddrs(&ifaddr) != -1)
-    {
-        for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
-        {
-            if (ifa->ifa_addr == NULL)
-                continue;
-
-            if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
-                if (interface == NULL) {
-                    *ip = strdup(host);
-                    status = CELIX_SUCCESS;
-                }
-                else if (strcmp(ifa->ifa_name, interface) == 0) {
-                    *ip = strdup(host);
-                    status = CELIX_SUCCESS;
-                }
-            }
-        }
-
-        freeifaddrs(ifaddr);
-    }
-
-    return status;
-}
-
-
-celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description)
-{
-    celix_status_t status = CELIX_SUCCESS;
-
-    properties_destroy((*description)->properties);
-    free((*description)->service);
-    free(*description);
-
-    return status;
-}
-
-
-celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services) {
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services) {
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *out) {
-    celix_status_t status = CELIX_SUCCESS;
-    import_registration_pt import = NULL;
-
-    const char *objectClass = properties_get(endpointDescription->properties, "objectClass");
-    const char *serviceVersion = properties_get(endpointDescription->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION);
-
-    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
-    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "Registering service factory (proxy) for service '%s'\n", objectClass);
-
-    if (objectClass != NULL) {
-        status = importRegistration_create(admin->context, endpointDescription, objectClass, serviceVersion, &import);
-    }
-    if (status == CELIX_SUCCESS && import != NULL) {
-        importRegistration_setSendFn(import, (send_func_type) remoteServiceAdmin_send, admin);
-    }
-
-    if (status == CELIX_SUCCESS && import != NULL) {
-        status = importRegistration_start(import);
-    }
-
-    celixThreadMutex_lock(&admin->importedServicesLock);
-    arrayList_add(admin->importedServices, import);
-    celixThreadMutex_unlock(&admin->importedServicesLock);
-
-    if (status == CELIX_SUCCESS) {
-        *out = import;
-    }
-
-    return status;
-}
-
-
-celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
-    celix_status_t status = CELIX_SUCCESS;
-    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing imported service");
-
-    celixThreadMutex_lock(&admin->importedServicesLock);
-    int i;
-    int size = arrayList_size(admin->importedServices);
-    import_registration_pt  current  = NULL;
-    for (i = 0; i < size; i += 1) {
-        current = arrayList_get(admin->importedServices, i);
-        if (current == registration) {
-            arrayList_remove(admin->importedServices, i);
-            importRegistration_close(current);
-            importRegistration_destroy(current);
-            break;
-        }
-    }
-    celixThreadMutex_unlock(&admin->importedServicesLock);
-
-    return status;
-}
-
-
-static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
-    remote_service_admin_pt  rsa = handle;
-    struct post post;
-    post.readptr = request;
-    post.size = strlen(request);
-
-    struct get get;
-    get.size = 0;
-    get.writeptr = malloc(1);
-
-    char *serviceUrl = (char*)properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
-    char url[256];
-    snprintf(url, 256, "%s", serviceUrl);
-
-    // assume the default timeout
-    int timeout = DEFAULT_TIMEOUT;
-
-    const char *timeoutStr = NULL;
-    // Check if the endpoint has a timeout, if so, use it.
-    timeoutStr = (char*) properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
-    if (timeoutStr == NULL) {
-        // If not, get the global variable and use that one.
-        bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
-    }
-
-    // Update timeout if a property is used to set it.
-    if (timeoutStr != NULL) {
-        timeout = atoi(timeoutStr);
-    }
-
-    celix_status_t status = CELIX_SUCCESS;
-    CURL *curl;
-    CURLcode res;
-
-    curl = curl_easy_init();
-    if(!curl) {
-        status = CELIX_ILLEGAL_STATE;
-    } else {
-        curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
-        curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
-        curl_easy_setopt(curl, CURLOPT_URL, url);
-        curl_easy_setopt(curl, CURLOPT_POST, 1L);
-        curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
-        curl_easy_setopt(curl, CURLOPT_READDATA, &post);
-        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
-        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
-        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
-        logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
-        res = curl_easy_perform(curl);
-
-        *reply = get.writeptr;
-        *replyStatus = res;
-
-        curl_easy_cleanup(curl);
-    }
-
-    return status;
-}
-
-static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp) {
-    struct post *post = userp;
-
-    if (post->size) {
-        *(char *) ptr = post->readptr[0];
-        post->readptr++;
-        post->size--;
-        return 1;
-    }
-
-    return 0;
-}
-
-static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {
-    size_t realsize = size * nmemb;
-    struct get *mem = (struct get *)userp;
-
-    mem->writeptr = realloc(mem->writeptr, mem->size + realsize + 1);
-    if (mem->writeptr == NULL) {
-        /* out of memory! */
-        printf("not enough memory (realloc returned NULL)");
-        exit(EXIT_FAILURE);
-    }
-
-    memcpy(&(mem->writeptr[mem->size]), contents, realsize);
-    mem->size += realsize;
-    mem->writeptr[mem->size] = 0;
-
-    return realsize;
-}
-
-
-static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...) {
-    va_list ap;
-    va_start(ap, msg);
-    int levels[5] = {0, OSGI_LOGSERVICE_ERROR, OSGI_LOGSERVICE_WARNING, OSGI_LOGSERVICE_INFO, OSGI_LOGSERVICE_DEBUG};
-
-    char buf1[256];
-    snprintf(buf1, 256, "FILE:%s, LINE:%i, MSG:", file, line);
-
-    char buf2[256];
-    vsnprintf(buf2, 256, msg, ap);
-    logHelper_log(admin->loghelper, levels[level], "%s%s", buf1, buf2);
-    va_end(ap);
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c
new file mode 100644
index 0000000..1b1eb36
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c
@@ -0,0 +1,98 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include "dfi_utils.h"
+#include <stdlib.h>
+#include <unistd.h>
+
+static celix_status_t dfi_findFileForFramework(bundle_context_pt context, const char *fileName, FILE **out) {
+    celix_status_t  status;
+
+    char pwd[1024];
+    char path[1024];
+    const char *extPath = NULL;
+   
+    status = bundleContext_getProperty(context, "CELIX_FRAMEWORK_EXTENDER_PATH", &extPath);
+    if (status != CELIX_SUCCESS || extPath == NULL) {
+        getcwd(pwd, sizeof(pwd));
+        extPath = pwd;
+    }
+
+    snprintf(path, sizeof(path), "%s/%s", extPath, fileName);
+
+    if (status == CELIX_SUCCESS) {
+        FILE *df = fopen(path, "r");
+        if (df == NULL) {
+            status = CELIX_FILE_IO_EXCEPTION;
+        } else {
+            *out = df;
+        }
+    }
+
+    return status;
+}
+
+static celix_status_t dfi_findFileForBundle(bundle_pt bundle, const char *fileName, FILE **out) {
+    celix_status_t  status;
+
+    char *path = NULL;
+    char metaInfFileName[512];
+    snprintf(metaInfFileName, sizeof(metaInfFileName), "META-INF/descriptors/%s", fileName);
+
+    status = bundle_getEntry(bundle, fileName, &path);
+    
+    if (status != CELIX_SUCCESS || path == NULL) {
+        status = bundle_getEntry(bundle, metaInfFileName, &path);
+    }
+
+    if (status == CELIX_SUCCESS && path != NULL) {
+        FILE *df = fopen(path, "r");
+        if (df == NULL) {
+            status = CELIX_FILE_IO_EXCEPTION;
+        } else {
+            *out = df;
+        }
+
+    }
+
+    free(path);
+    return status;
+}
+
+celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out) {
+    celix_status_t  status;
+    char fileName[128];
+
+    snprintf(fileName, 128, "%s.descriptor", name);
+
+    long id;
+    status = bundle_getBundleId(bundle, &id);
+    
+    if (status == CELIX_SUCCESS) {
+        if (id == 0) {
+            //framework bundle
+            status = dfi_findFileForFramework(context, fileName, out);
+        } else {
+            //normal bundle
+            status = dfi_findFileForBundle(bundle, fileName, out);
+        }
+    }
+
+    return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h
new file mode 100644
index 0000000..cec8aa1
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h
@@ -0,0 +1,30 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#ifndef DFI_UTILS_H_
+#define DFI_UTILS_H_
+
+#include "bundle.h"
+#include "bundle_context.h"
+#include <stdio.h>
+#include "celix_errno.h"
+
+
+celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out);
+
+#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c
new file mode 100644
index 0000000..b83b5a8
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c
@@ -0,0 +1,251 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <jansson.h>
+#include <dyn_interface.h>
+#include <json_serializer.h>
+#include <remote_constants.h>
+#include <remote_service_admin.h>
+#include <service_tracker_customizer.h>
+#include <service_tracker.h>
+#include <json_rpc.h>
+#include "constants.h"
+#include "export_registration_dfi.h"
+#include "dfi_utils.h"
+
+struct export_reference {
+    endpoint_description_pt endpoint; //owner
+    service_reference_pt reference;
+};
+
+struct export_registration {
+    bundle_context_pt  context;
+    struct export_reference exportReference;
+    char *servId;
+    dyn_interface_type *intf; //owner
+    service_tracker_pt tracker;
+
+    celix_thread_mutex_t mutex;
+    void *service; //protected by mutex
+
+    //TODO add tracker and lock
+    bool closed;
+};
+
+static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service);
+static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service);
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *out) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    const char *servId = NULL;
+    status = serviceReference_getProperty(reference, "service.id", &servId);
+    if (status != CELIX_SUCCESS) {
+        logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Cannot find service.id for ref");
+    }
+
+    export_registration_pt reg = NULL;
+    if (status == CELIX_SUCCESS) {
+        reg = calloc(1, sizeof(*reg));
+        if (reg == NULL) {
+            status = CELIX_ENOMEM;
+        }
+    }
+
+
+    if (status == CELIX_SUCCESS) {
+        reg->context = context;
+        reg->exportReference.endpoint = endpoint;
+        reg->exportReference.reference = reference;
+        reg->closed = false;
+
+        celixThreadMutex_create(&reg->mutex, NULL);
+    }
+
+    const char *exports = NULL;
+    CELIX_DO_IF(status, serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports));
+
+    bundle_pt bundle = NULL;
+    CELIX_DO_IF(status, serviceReference_getBundle(reference, &bundle));
+
+    FILE *descriptor = NULL;
+    if (status == CELIX_SUCCESS) {
+        status = dfi_findDescriptor(context, bundle, exports, &descriptor);
+    }
+
+    if (status != CELIX_SUCCESS || descriptor == NULL) {
+        status = CELIX_BUNDLE_EXCEPTION;
+        logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", exports);
+    }
+
+    if (status == CELIX_SUCCESS) {
+        int rc = dynInterface_parse(descriptor, &reg->intf);
+        fclose(descriptor);
+        if (rc != 0) {
+            status = CELIX_BUNDLE_EXCEPTION;
+            logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "RSA: Error parsing service descriptor.");
+        }
+        else{
+            /* Add the interface version as a property in the properties_map */
+            char* intfVersion = NULL;
+            dynInterface_getVersionString(reg->intf, &intfVersion);
+            const char *serviceVersion = properties_get(endpoint->properties,(char*) CELIX_FRAMEWORK_SERVICE_VERSION);
+            if(serviceVersion!=NULL){
+            	if(strcmp(serviceVersion,intfVersion)!=0){
+            		logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Service version (%s) and interface version from the descriptor (%s) are not the same!",serviceVersion,intfVersion);
+            	}
+            }
+            else{
+            	properties_set(endpoint->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION, intfVersion);
+            }
+        }
+    } 
+
+    if (status == CELIX_SUCCESS) {
+        service_tracker_customizer_pt cust = NULL;
+        status = serviceTrackerCustomizer_create(reg, NULL, (void *) exportRegistration_addServ, NULL,
+                                                 (void *) exportRegistration_removeServ, &cust);
+        if (status == CELIX_SUCCESS) {
+            char filter[32];
+            snprintf(filter, 32, "(service.id=%s)", servId);
+            status = serviceTracker_createWithFilter(reg->context, filter, cust, &reg->tracker);
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        *out = reg;
+    } else {
+        logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Error creating export registration");
+        exportRegistration_destroy(reg);
+    }
+
+    return status;
+}
+
+celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **responseOut, int *responseLength) {
+    int status = CELIX_SUCCESS;
+
+    //printf("calling for '%s'\n");
+
+    *responseLength = -1;
+    celixThreadMutex_lock(&export->mutex);
+    status = jsonRpc_call(export->intf, export->service, data, responseOut);
+    celixThreadMutex_unlock(&export->mutex);
+
+    return status;
+}
+
+void exportRegistration_destroy(export_registration_pt reg) {
+    if (reg != NULL) {
+        if (reg->intf != NULL) {
+            dyn_interface_type *intf = reg->intf;
+            reg->intf = NULL;
+            dynInterface_destroy(intf);
+        }
+
+        if (reg->exportReference.endpoint != NULL) {
+            endpoint_description_pt ep = reg->exportReference.endpoint;
+            reg->exportReference.endpoint = NULL;
+            endpointDescription_destroy(ep);
+        }
+        if (reg->tracker != NULL) {
+            serviceTracker_destroy(reg->tracker);
+        }
+        celixThreadMutex_destroy(&reg->mutex);
+
+        free(reg);
+    }
+}
+
+celix_status_t exportRegistration_start(export_registration_pt reg) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    serviceTracker_open(reg->tracker);
+    return status;
+}
+
+
+celix_status_t exportRegistration_stop(export_registration_pt reg) {
+    celix_status_t status = CELIX_SUCCESS;
+    if (status == CELIX_SUCCESS) {
+        status = bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
+        serviceTracker_close(reg->tracker);
+    }
+    return status;
+}
+
+static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service) {
+    celixThreadMutex_lock(&reg->mutex);
+    reg->service = service;
+    celixThreadMutex_unlock(&reg->mutex);
+}
+
+static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service) {
+    celixThreadMutex_lock(&reg->mutex);
+    if (reg->service == service) {
+        reg->service = NULL;
+    }
+    celixThreadMutex_unlock(&reg->mutex);
+}
+
+
+celix_status_t exportRegistration_close(export_registration_pt reg) {
+    celix_status_t status = CELIX_SUCCESS;
+    exportRegistration_stop(reg);
+    return status;
+}
+
+
+celix_status_t exportRegistration_getException(export_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *out) {
+    celix_status_t status = CELIX_SUCCESS;
+    export_reference_pt ref = calloc(1, sizeof(*ref));
+    if (ref != NULL) {
+        ref->endpoint = registration->exportReference.endpoint;
+        ref->reference = registration->exportReference.reference;
+    } else {
+        status = CELIX_ENOMEM;
+    }
+
+    if (status == CELIX_SUCCESS) {
+        *out = ref;
+    }
+
+    return status;
+}
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
+    celix_status_t status = CELIX_SUCCESS;
+    *endpoint = reference->endpoint;
+    return status;
+}
+
+celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *ref) {
+    celix_status_t status = CELIX_SUCCESS;
+    *ref = reference->reference;
+    return status;
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h
new file mode 100644
index 0000000..93f37ba
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h
@@ -0,0 +1,38 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef CELIX_EXPORT_REGISTRATION_DFI_H
+#define CELIX_EXPORT_REGISTRATION_DFI_H
+
+
+#include "export_registration.h"
+#include "log_helper.h"
+#include "endpoint_description.h"
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *registration);
+celix_status_t exportRegistration_close(export_registration_pt registration);
+void exportRegistration_destroy(export_registration_pt registration);
+
+celix_status_t exportRegistration_start(export_registration_pt registration);
+celix_status_t exportRegistration_stop(export_registration_pt registration);
+
+celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **response, int *responseLength);
+
+
+#endif //CELIX_EXPORT_REGISTRATION_DFI_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c
new file mode 100644
index 0000000..0b8dcf7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c
@@ -0,0 +1,402 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <stdlib.h>
+#include <jansson.h>
+#include <json_rpc.h>
+#include <assert.h>
+#include "version.h"
+#include "json_serializer.h"
+#include "dyn_interface.h"
+#include "import_registration.h"
+#include "import_registration_dfi.h"
+
+struct import_registration {
+    bundle_context_pt context;
+    endpoint_description_pt  endpoint; //TODO owner? -> free when destroyed
+    const char *classObject; //NOTE owned by endpoint
+    version_pt version;
+
+    celix_thread_mutex_t mutex; //protects send & sendhandle
+    send_func_type send;
+    void *sendHandle;
+
+    service_factory_pt factory;
+    service_registration_pt factoryReg;
+
+    hash_map_pt proxies; //key -> bundle, value -> service_proxy
+    celix_thread_mutex_t proxiesMutex; //protects proxies
+};
+
+struct service_proxy {
+    dyn_interface_type *intf;
+    void *service;
+    size_t count;
+};
+
+static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle,
+                                              struct service_proxy **proxy);
+static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal);
+static void importRegistration_destroyProxy(struct service_proxy *proxy);
+static void importRegistration_clearProxies(import_registration_pt import);
+
+celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt endpoint, const char *classObject, const char* serviceVersion,
+                                         import_registration_pt *out) {
+    celix_status_t status = CELIX_SUCCESS;
+    import_registration_pt reg = calloc(1, sizeof(*reg));
+
+    if (reg != NULL) {
+        reg->factory = calloc(1, sizeof(*reg->factory));
+    }
+
+    if (reg != NULL && reg->factory != NULL) {
+        reg->context = context;
+        reg->endpoint = endpoint;
+        reg->classObject = classObject;
+        reg->proxies = hashMap_create(NULL, NULL, NULL, NULL);
+
+        celixThreadMutex_create(&reg->mutex, NULL);
+        celixThreadMutex_create(&reg->proxiesMutex, NULL);
+        status = version_createVersionFromString((char*)serviceVersion,&(reg->version));
+
+        reg->factory->handle = reg;
+        reg->factory->getService = (void *)importRegistration_getService;
+        reg->factory->ungetService = (void *)importRegistration_ungetService;
+    } else {
+        status = CELIX_ENOMEM;
+    }
+
+    if (status == CELIX_SUCCESS) {
+        //printf("IMPORT REGISTRATION IS %p\n", reg);
+        *out = reg;
+    }
+    else{
+    	importRegistration_destroy(reg);
+    }
+
+    return status;
+}
+
+
+celix_status_t importRegistration_setSendFn(import_registration_pt reg,
+                                            send_func_type send,
+                                            void *handle) {
+    celixThreadMutex_lock(&reg->mutex);
+    reg->send = send;
+    reg->sendHandle = handle;
+    celixThreadMutex_unlock(&reg->mutex);
+
+    return CELIX_SUCCESS;
+}
+
+static void importRegistration_clearProxies(import_registration_pt import) {
+    if (import != NULL) {
+        pthread_mutex_lock(&import->proxiesMutex);
+        if (import->proxies != NULL) {
+            hash_map_iterator_pt iter = hashMapIterator_create(import->proxies);
+            while (hashMapIterator_hasNext(iter)) {
+                hash_map_entry_pt  entry = hashMapIterator_nextEntry(iter);
+                struct service_proxy *proxy = hashMapEntry_getValue(entry);
+                importRegistration_destroyProxy(proxy);
+            }
+            hashMapIterator_destroy(iter);
+        }
+        pthread_mutex_unlock(&import->proxiesMutex);
+    }
+}
+
+void importRegistration_destroy(import_registration_pt import) {
+    if (import != NULL) {
+        if (import->proxies != NULL) {
+            hashMap_destroy(import->proxies, false, false);
+            import->proxies = NULL;
+        }
+
+        pthread_mutex_destroy(&import->mutex);
+        pthread_mutex_destroy(&import->proxiesMutex);
+
+        if (import->factory != NULL) {
+            free(import->factory);
+        }
+
+        if(import->version!=NULL){
+        	version_destroy(import->version);
+        }
+        free(import);
+    }
+}
+
+celix_status_t importRegistration_start(import_registration_pt import) {
+    celix_status_t  status = CELIX_SUCCESS;
+    if (import->factoryReg == NULL && import->factory != NULL) {
+        properties_pt props = NULL;
+        properties_copy(import->endpoint->properties, &props);
+        status = bundleContext_registerServiceFactory(import->context, (char *)import->classObject, import->factory, props, &import->factoryReg);
+    } else {
+        status = CELIX_ILLEGAL_STATE;
+    }
+    return status;
+}
+
+celix_status_t importRegistration_stop(import_registration_pt import) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (import->factoryReg != NULL) {
+        serviceRegistration_unregister(import->factoryReg);
+        import->factoryReg = NULL;
+    }
+
+    importRegistration_clearProxies(import);
+
+    return status;
+}
+
+
+celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
+    celix_status_t  status = CELIX_SUCCESS;
+
+    /*
+    module_pt module = NULL;
+    char *name = NULL;
+    bundle_getCurrentModule(bundle, &module);
+    module_getSymbolicName(module, &name);
+    printf("getting service for bundle '%s'\n", name);
+     */
+
+
+    pthread_mutex_lock(&import->proxiesMutex);
+    struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
+    if (proxy == NULL) {
+        status = importRegistration_createProxy(import, bundle, &proxy);
+        if (status == CELIX_SUCCESS) {
+            hashMap_put(import->proxies, bundle, proxy);
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        proxy->count += 1;
+        *out = proxy->service;
+    }
+    pthread_mutex_unlock(&import->proxiesMutex);
+
+    return status;
+}
+
+static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle, struct service_proxy **out) {
+    celix_status_t  status;
+    dyn_interface_type* intf = NULL;
+    FILE *descriptor = NULL;
+
+    status = dfi_findDescriptor(import->context, bundle, import->classObject, &descriptor);
+
+    if (status != CELIX_SUCCESS || descriptor == NULL) {
+        //TODO use log helper logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", import->classObject);
+        fprintf(stderr, "RSA_DFI: Cannot find/open descriptor for '%s'", import->classObject);
+        return CELIX_BUNDLE_EXCEPTION;
+    }
+
+    if (status == CELIX_SUCCESS) {
+        int rc = dynInterface_parse(descriptor, &intf);
+        fclose(descriptor);
+        if (rc != 0 || intf==NULL) {
+            return CELIX_BUNDLE_EXCEPTION;
+        }
+    }
+
+    /* Check if the imported service version is compatible with the one in the consumer descriptor */
+    version_pt consumerVersion = NULL;
+    bool isCompatible = false;
+    dynInterface_getVersion(intf,&consumerVersion);
+    version_isCompatible(consumerVersion,import->version,&isCompatible);
+
+    if(!isCompatible){
+    	char* cVerString = NULL;
+    	char* pVerString = NULL;
+    	version_toString(consumerVersion,&cVerString);
+    	version_toString(import->version,&pVerString);
+    	printf("Service version mismatch: consumer has %s, provider has %s. NOT creating proxy.\n",cVerString,pVerString);
+    	dynInterface_destroy(intf);
+    	free(cVerString);
+    	free(pVerString);
+    	status = CELIX_SERVICE_EXCEPTION;
+    }
+
+    struct service_proxy *proxy = NULL;
+    if (status == CELIX_SUCCESS) {
+        proxy = calloc(1, sizeof(*proxy));
+        if (proxy == NULL) {
+            status = CELIX_ENOMEM;
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+    	proxy->intf = intf;
+        size_t count = dynInterface_nrOfMethods(proxy->intf);
+        proxy->service = calloc(1 + count, sizeof(void *));
+        if (proxy->service == NULL) {
+            status = CELIX_ENOMEM;
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        void **serv = proxy->service;
+        serv[0] = import;
+
+        struct methods_head *list = NULL;
+        dynInterface_methods(proxy->intf, &list);
+        struct method_entry *entry = NULL;
+        void (*fn)(void) = NULL;
+        int index = 0;
+        TAILQ_FOREACH(entry, list, entries) {
+            int rc = dynFunction_createClosure(entry->dynFunc, importRegistration_proxyFunc, entry, &fn);
+            serv[index + 1] = fn;
+            index += 1;
+
+            if (rc != 0) {
+                status = CELIX_BUNDLE_EXCEPTION;
+                break;
+            }
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        *out = proxy;
+    } else if (proxy != NULL) {
+        if (proxy->intf != NULL) {
+            dynInterface_destroy(proxy->intf);
+            proxy->intf = NULL;
+        }
+        free(proxy->service);
+        free(proxy);
+    }
+
+    return status;
+}
+
+static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal) {
+    int  status = CELIX_SUCCESS;
+    struct method_entry *entry = userData;
+    import_registration_pt import = *((void **)args[0]);
+
+    if (import == NULL || import->send == NULL) {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+
+    char *invokeRequest = NULL;
+    if (status == CELIX_SUCCESS) {
+        status = jsonRpc_prepareInvokeRequest(entry->dynFunc, entry->id, args, &invokeRequest);
+        //printf("Need to send following json '%s'\n", invokeRequest);
+    }
+
+
+    if (status == CELIX_SUCCESS) {
+        char *reply = NULL;
+        int rc = 0;
+        //printf("sending request\n");
+        celixThreadMutex_lock(&import->mutex);
+        if (import->send != NULL) {
+            import->send(import->sendHandle, import->endpoint, invokeRequest, &reply, &rc);
+        }
+        celixThreadMutex_unlock(&import->mutex);
+        //printf("request sended. got reply '%s' with status %i\n", reply, rc);
+
+        if (rc == 0) {
+            //fjprintf("Handling reply '%s'\n", reply);
+            status = jsonRpc_handleReply(entry->dynFunc, reply, args);
+        }
+
+        *(int *) returnVal = rc;
+
+        free(invokeRequest); //Allocated by json_dumps in jsonRpc_prepareInvokeRequest
+        free(reply); //Allocated by json_dumps in remoteServiceAdmin_send through curl call
+    }
+
+    if (status != CELIX_SUCCESS) {
+        //TODO log error
+    }
+}
+
+celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
+    celix_status_t  status = CELIX_SUCCESS;
+
+    assert(import != NULL);
+    assert(import->proxies != NULL);
+
+    pthread_mutex_lock(&import->proxiesMutex);
+
+    struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
+    if (proxy != NULL) {
+        if (*out == proxy->service) {
+            proxy->count -= 1;
+        } else {
+            status = CELIX_ILLEGAL_ARGUMENT;
+        }
+
+        if (proxy->count == 0) {
+            hashMap_remove(import->proxies, bundle);
+            importRegistration_destroyProxy(proxy);
+        }
+    }
+
+    pthread_mutex_unlock(&import->proxiesMutex);
+
+    return status;
+}
+
+static void importRegistration_destroyProxy(struct service_proxy *proxy) {
+    if (proxy != NULL) {
+        if (proxy->intf != NULL) {
+            dynInterface_destroy(proxy->intf);
+        }
+        if (proxy->service != NULL) {
+            free(proxy->service);
+        }
+        free(proxy);
+    }
+}
+
+
+celix_status_t importRegistration_close(import_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    importRegistration_stop(registration);
+    return status;
+}
+
+celix_status_t importRegistration_getException(import_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+}
+
+celix_status_t importReference_getImportedService(import_reference_pt reference) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h
new file mode 100644
index 0000000..aac4bc7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h
@@ -0,0 +1,44 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef CELIX_IMPORT_REGISTRATION_DFI_H
+#define CELIX_IMPORT_REGISTRATION_DFI_H
+
+#include "import_registration.h"
+#include "dfi_utils.h"
+
+#include <celix_errno.h>
+
+typedef void (*send_func_type)(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
+
+celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt description, const char *classObject, const char* serviceVersion,
+                                         import_registration_pt *import);
+celix_status_t importRegistration_close(import_registration_pt import);
+void importRegistration_destroy(import_registration_pt import);
+
+celix_status_t importRegistration_setSendFn(import_registration_pt reg,
+                                            send_func_type,
+                                            void *handle);
+celix_status_t importRegistration_start(import_registration_pt import);
+celix_status_t importRegistration_stop(import_registration_pt import);
+
+celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
+celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
+
+#endif //CELIX_IMPORT_REGISTRATION_DFI_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c
new file mode 100644
index 0000000..d4cc765
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c
@@ -0,0 +1,124 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_activator.c
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <remote_service_admin.h>
+
+#include "remote_service_admin_dfi.h"
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+
+#include "export_registration_dfi.h"
+#include "import_registration_dfi.h"
+
+struct activator {
+	remote_service_admin_pt admin;
+	remote_service_admin_service_pt adminService;
+	service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator;
+
+	activator = calloc(1, sizeof(*activator));
+	if (!activator) {
+		status = CELIX_ENOMEM;
+	} else {
+		activator->admin = NULL;
+		activator->registration = NULL;
+
+		*userData = activator;
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	remote_service_admin_service_pt remoteServiceAdmin = NULL;
+
+	status = remoteServiceAdmin_create(context, &activator->admin);
+	if (status == CELIX_SUCCESS) {
+		remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
+		if (!remoteServiceAdmin) {
+			status = CELIX_ENOMEM;
+		} else {
+			remoteServiceAdmin->admin = activator->admin;
+			remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
+
+			remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
+			remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
+			remoteServiceAdmin->importService = remoteServiceAdmin_importService;
+
+			remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
+			remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
+
+			remoteServiceAdmin->exportRegistration_close = remoteServiceAdmin_removeExportedService;
+			remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
+			remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
+
+			remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
+			remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
+
+			remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
+			remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
+			remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
+
+			status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
+			activator->adminService = remoteServiceAdmin;
+		}
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+    celix_status_t status = CELIX_SUCCESS;
+    struct activator *activator = userData;
+
+    serviceRegistration_unregister(activator->registration);
+    activator->registration = NULL;
+
+    remoteServiceAdmin_stop(activator->admin);
+    remoteServiceAdmin_destroy(&activator->admin);
+
+    free(activator->adminService);
+
+    return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	free(activator);
+
+	return status;
+}
+
+


[04/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/src/topology_manager.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/src/topology_manager.c b/remote_services/topology_manager/private/src/topology_manager.c
deleted file mode 100644
index 6472b01..0000000
--- a/remote_services/topology_manager/private/src/topology_manager.c
+++ /dev/null
@@ -1,985 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * topology_manager.c
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "celixbool.h"
-#include "topology_manager.h"
-#include "bundle_context.h"
-#include "constants.h"
-#include "bundle.h"
-#include "remote_service_admin.h"
-#include "remote_constants.h"
-#include "filter.h"
-#include "listener_hook_service.h"
-#include "utils.h"
-#include "service_reference.h"
-#include "service_registration.h"
-#include "log_service.h"
-#include "log_helper.h"
-#include "topology_manager.h"
-#include "scope.h"
-#include "hash_map.h"
-
-struct topology_manager {
-	bundle_context_pt context;
-
-	celix_thread_mutex_t rsaListLock;
-	celix_thread_mutexattr_t rsaListLockAttr;
-	array_list_pt rsaList;
-
-	celix_thread_mutex_t listenerListLock;
-	hash_map_pt listenerList;
-
-	celix_thread_mutex_t exportedServicesLock;
-	hash_map_pt exportedServices;
-
-	celix_thread_mutex_t importedServicesLock;
-	celix_thread_mutexattr_t importedServicesLockAttr;
-	hash_map_pt importedServices;
-
-	scope_pt scope;
-
-	log_helper_pt loghelper;
-};
-
-celix_status_t topologyManager_exportScopeChanged(void *handle, char *service_name);
-celix_status_t topologyManager_importScopeChanged(void *handle, char *service_name);
-celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations);
-celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export);
-
-celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager, void **scope) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*manager = calloc(1, sizeof(**manager));
-
-	if (!*manager) {
-		return CELIX_ENOMEM;
-	}
-
-	(*manager)->context = context;
-	(*manager)->rsaList = NULL;
-
-	arrayList_create(&(*manager)->rsaList);
-
-
-	celixThreadMutexAttr_create(&(*manager)->rsaListLockAttr);
-	celixThreadMutexAttr_settype(&(*manager)->rsaListLockAttr, CELIX_THREAD_MUTEX_RECURSIVE);
-	celixThreadMutex_create(&(*manager)->rsaListLock, &(*manager)->rsaListLockAttr);
-
-	celixThreadMutexAttr_create(&(*manager)->importedServicesLockAttr);
-	celixThreadMutexAttr_settype(&(*manager)->importedServicesLockAttr, CELIX_THREAD_MUTEX_RECURSIVE);
-	celixThreadMutex_create(&(*manager)->importedServicesLock, &(*manager)->importedServicesLockAttr);
-
-	celixThreadMutex_create(&(*manager)->exportedServicesLock, NULL);
-	celixThreadMutex_create(&(*manager)->listenerListLock, NULL);
-
-	(*manager)->listenerList = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
-	(*manager)->exportedServices = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
-	(*manager)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
-
-	status = scope_scopeCreate(*manager, &(*manager)->scope);
-	scope_setExportScopeChangedCallback((*manager)->scope, topologyManager_exportScopeChanged);
-	scope_setImportScopeChangedCallback((*manager)->scope, topologyManager_importScopeChanged);
-	*scope = (*manager)->scope;
-
-	(*manager)->loghelper = logHelper;
-
-
-	return status;
-}
-
-celix_status_t topologyManager_destroy(topology_manager_pt manager) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&manager->listenerListLock);
-	hashMap_destroy(manager->listenerList, false, false);
-
-	celixThreadMutex_unlock(&manager->listenerListLock);
-	celixThreadMutex_destroy(&manager->listenerListLock);
-
-	celixThreadMutex_lock(&manager->rsaListLock);
-
-	arrayList_destroy(manager->rsaList);
-
-	celixThreadMutex_unlock(&manager->rsaListLock);
-	celixThreadMutex_destroy(&manager->rsaListLock);
-	celixThreadMutexAttr_destroy(&manager->rsaListLockAttr);
-
-	celixThreadMutex_lock(&manager->exportedServicesLock);
-
-	hashMap_destroy(manager->exportedServices, false, false);
-
-	celixThreadMutex_unlock(&manager->exportedServicesLock);
-	celixThreadMutex_destroy(&manager->exportedServicesLock);
-
-	celixThreadMutex_lock(&manager->importedServicesLock);
-
-	hashMap_destroy(manager->importedServices, false, false);
-
-	celixThreadMutex_unlock(&manager->importedServicesLock);
-	celixThreadMutex_destroy(&manager->importedServicesLock);
-	celixThreadMutexAttr_destroy(&manager->importedServicesLockAttr);
-
-	scope_scopeDestroy(manager->scope);
-	free(manager);
-
-	return status;
-}
-
-celix_status_t topologyManager_closeImports(topology_manager_pt manager) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&manager->importedServicesLock);
-
-	hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
-	while (hashMapIterator_hasNext(iter)) {
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-		endpoint_description_pt ep = hashMapEntry_getKey(entry);
-		hash_map_pt imports = hashMapEntry_getValue(entry);
-
-		if (imports != NULL) {
-			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", ep->service, ep->id);
-			hash_map_iterator_pt importsIter = hashMapIterator_create(imports);
-
-			while (hashMapIterator_hasNext(importsIter)) {
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter);
-
-				remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
-				import_registration_pt import = hashMapEntry_getValue(entry);
-
-				status = rsa->importRegistration_close(rsa->admin, import);
-				if (status == CELIX_SUCCESS) {
-					hashMapIterator_remove(importsIter);
-				}
-			}
-			hashMapIterator_destroy(importsIter);
-
-			hashMapIterator_remove(iter);
-
-			hashMap_destroy(imports, false, false);
-		}
-	}
-	hashMapIterator_destroy(iter);
-
-	status = celixThreadMutex_unlock(&manager->importedServicesLock);
-
-	return status;
-}
-
-celix_status_t topologyManager_rsaAdding(void * handle, service_reference_pt reference, void **service) {
-	celix_status_t status;
-	topology_manager_pt manager = (topology_manager_pt) handle;
-
-	status = bundleContext_getService(manager->context, reference, service);
-
-	return status;
-}
-
-celix_status_t topologyManager_rsaAdded(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status;
-	topology_manager_pt manager = (topology_manager_pt) handle;
-	properties_pt serviceProperties = NULL;
-	remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service;
-	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added RSA");
-
-	status = celixThreadMutex_lock(&manager->rsaListLock);
-
-	if (status == CELIX_SUCCESS) {
-		arrayList_add(manager->rsaList, rsa);
-		status = celixThreadMutex_unlock(&manager->rsaListLock);
-	}
-
-	// add already imported services to new rsa
-	if (status == CELIX_SUCCESS) {
-		status = celixThreadMutex_lock(&manager->importedServicesLock);
-
-		if (status == CELIX_SUCCESS) {
-			hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices);
-
-			while (hashMapIterator_hasNext(importedServicesIterator)) {
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator);
-				endpoint_description_pt endpoint = hashMapEntry_getKey(entry);
-				if (scope_allowImport(manager->scope, endpoint)) {
-					import_registration_pt import = NULL;
-					status = rsa->importService(rsa->admin, endpoint, &import);
-
-					if (status == CELIX_SUCCESS) {
-						hash_map_pt imports = hashMapEntry_getValue(entry);
-
-						if (imports == NULL) {
-							imports = hashMap_create(NULL, NULL, NULL, NULL);
-							hashMap_put(manager->importedServices,endpoint,imports);
-						}
-
-						hashMap_put(imports, service, import);
-					}
-				}
-			}
-
-			hashMapIterator_destroy(importedServicesIterator);
-
-			celixThreadMutex_unlock(&manager->importedServicesLock);
-		}
-	}
-
-	// add already exported services to new rsa
-	if (status == CELIX_SUCCESS) {
-		status = celixThreadMutex_lock(&manager->exportedServicesLock);
-
-		if (status == CELIX_SUCCESS) {
-			hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices);
-
-			while (hashMapIterator_hasNext(exportedServicesIterator)) {
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator);
-				service_reference_pt reference = hashMapEntry_getKey(entry);
-				const char* serviceId = NULL;
-
-				serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
-
-				scope_getExportProperties(manager->scope, reference, &serviceProperties);
-
-				array_list_pt endpoints = NULL;
-				status = rsa->exportService(rsa->admin, (char*)serviceId, serviceProperties, &endpoints);
-
-				if (status == CELIX_SUCCESS) {
-					hash_map_pt exports = hashMapEntry_getValue(entry);
-
-					if (exports == NULL) {
-						exports = hashMap_create(NULL, NULL, NULL, NULL);
-						hashMap_put(manager->exportedServices,reference,exports);
-					}
-
-					hashMap_put(exports, rsa, endpoints);
-					status = topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints);
-				}
-			}
-
-			hashMapIterator_destroy(exportedServicesIterator);
-
-			celixThreadMutex_unlock(&manager->exportedServicesLock);
-		}
-	}
-	return status;
-}
-
-celix_status_t topologyManager_rsaModified(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	// Nop...
-
-	return status;
-}
-
-celix_status_t topologyManager_rsaRemoved(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-	topology_manager_pt manager = (topology_manager_pt) handle;
-	remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service;
-
-	if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
-		hash_map_iterator_pt iter = hashMapIterator_create(manager->exportedServices);
-
-		while (hashMapIterator_hasNext(iter)) {
-
-			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-			service_reference_pt key = hashMapEntry_getKey(entry);
-			hash_map_pt exports = hashMapEntry_getValue(entry);
-
-			/*
-			 * the problem here is that also the rsa has a a list of
-			 * endpoints which is destroyed when closing the exportRegistration
-			 */
-			array_list_pt exports_list = hashMap_get(exports, rsa);
-
-			if (exports_list != NULL) {
-				int exportsIter = 0;
-				int exportListSize = arrayList_size(exports_list);
-				for (exportsIter = 0; exports_list != NULL && exportsIter < exportListSize; exportsIter++) {
-					export_registration_pt export = arrayList_get(exports_list, exportsIter);
-					topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
-					rsa->exportRegistration_close(rsa->admin, export);
-				}
-			}
-
-			hashMap_remove(exports, rsa);
-			/*if(exports_list!=NULL){
-            	arrayList_destroy(exports_list);
-            }*/
-
-			if (hashMap_size(exports) == 0) {
-				hashMap_remove(manager->exportedServices, key);
-				hashMap_destroy(exports, false, false);
-
-				hashMapIterator_destroy(iter);
-				iter = hashMapIterator_create(manager->exportedServices);
-			}
-		}
-		hashMapIterator_destroy(iter);
-		celixThreadMutex_unlock(&manager->exportedServicesLock);
-	}
-
-	if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
-		hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
-
-		while (hashMapIterator_hasNext(iter)) {
-			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-			hash_map_pt imports = hashMapEntry_getValue(entry);
-
-			import_registration_pt import = hashMap_get(imports, rsa);
-
-			if (import != NULL) {
-				celix_status_t subStatus = rsa->importRegistration_close(rsa->admin, import);
-
-				if (subStatus == CELIX_SUCCESS) {
-					hashMap_remove(imports, rsa);
-				} else {
-					status = subStatus;
-				}
-			}
-		}
-		hashMapIterator_destroy(iter);
-		celixThreadMutex_unlock(&manager->importedServicesLock);
-	}
-
-	if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
-		arrayList_removeElement(manager->rsaList, rsa);
-		celixThreadMutex_unlock(&manager->rsaListLock);
-	}
-
-	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Removed RSA");
-
-	return status;
-}
-
-
-celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event) {
-	celix_status_t status = CELIX_SUCCESS;
-	service_listener_pt listen = listener;
-	topology_manager_pt manager = listen->handle;
-
-	const char* export = NULL;
-	const char* serviceId = NULL;
-	serviceReference_getProperty(event->reference, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export);
-	serviceReference_getProperty(event->reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
-
-	if (!export) {
-		// Nothing needs to be done: we're not interested...
-		return status;
-	}
-
-	switch (event->type) {
-	case OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED:
-		status = topologyManager_addExportedService(manager, event->reference, (char*)serviceId);
-		break;
-	case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED:
-		status = topologyManager_removeExportedService(manager, event->reference, (char*)serviceId);
-
-		if (status == CELIX_SUCCESS) {
-			status = topologyManager_addExportedService(manager, event->reference, (char*)serviceId);
-		}
-		break;
-	case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING:
-		status = topologyManager_removeExportedService(manager, event->reference, (char*)serviceId);
-		break;
-	case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH:
-		break;
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_exportScopeChanged(void *handle, char *filterStr) {
-	celix_status_t status = CELIX_SUCCESS;
-	topology_manager_pt manager = (topology_manager_pt) handle;
-	service_registration_pt reg = NULL;
-	const char* serviceId = NULL;
-	bool found;
-	properties_pt props;
-	filter_pt filter = filter_create(filterStr);
-
-	if (filter == NULL) {
-		printf("filter creating failed\n");
-		return CELIX_ENOMEM;
-	}
-
-	// add already exported services to new rsa
-	if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
-		hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices);
-		int size = hashMap_size(manager->exportedServices);
-		service_reference_pt *srvRefs = (service_reference_pt *) calloc(size, sizeof(service_reference_pt));
-		char **srvIds = (char **) calloc(size, sizeof(char*));
-		int nrFound = 0;
-
-		found = false;
-
-		while (hashMapIterator_hasNext(exportedServicesIterator)) {
-			hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator);
-			service_reference_pt reference = hashMapEntry_getKey(entry);
-			reg = NULL;
-			serviceReference_getServiceRegistration(reference, &reg);
-			if (reg != NULL) {
-				props = NULL;
-				serviceRegistration_getProperties(reg, &props);
-				status = filter_match(filter, props, &found);
-				if (found) {
-					srvRefs[nrFound] = reference;
-					serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
-					srvIds[nrFound++] = (char*)serviceId;
-				}
-			}
-		}
-
-		hashMapIterator_destroy(exportedServicesIterator);
-		celixThreadMutex_unlock(&manager->exportedServicesLock);
-
-		if (nrFound > 0) {
-			for (int i = 0; i < nrFound; i++) {
-				// Question: can srvRefs become invalid meanwhile??
-				const char* export = NULL;
-				serviceReference_getProperty(srvRefs[i], (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export);
-
-				if (export) {
-					celix_status_t substatus = topologyManager_removeExportedService(manager, srvRefs[i], srvIds[i]);
-
-					if (substatus != CELIX_SUCCESS) {
-						logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: Removal of exported service (%s) failed.", srvIds[i]);
-					} else {
-						substatus = topologyManager_addExportedService(manager, srvRefs[i], srvIds[i]);
-					}
-
-					if (substatus != CELIX_SUCCESS) {
-						status = substatus;
-					}
-				}
-			}
-		}
-
-		free(srvRefs);
-		free(srvIds);
-	}
-
-	filter_destroy(filter);
-
-	return status;
-}
-
-celix_status_t topologyManager_importScopeChanged(void *handle, char *service_name) {
-	celix_status_t status = CELIX_SUCCESS;
-	endpoint_description_pt endpoint;
-	topology_manager_pt manager = (topology_manager_pt) handle;
-	bool found = false;
-
-	// add already exported services to new rsa
-	if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
-		hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices);
-		while (!found && hashMapIterator_hasNext(importedServicesIterator)) {
-			hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator);
-			endpoint = hashMapEntry_getKey(entry);
-
-			entry = hashMap_getEntry(endpoint->properties, (void *) OSGI_FRAMEWORK_OBJECTCLASS);
-			char* name = (char *) hashMapEntry_getValue(entry);
-			// Test if a service with the same name is imported
-			if (strcmp(name, service_name) == 0) {
-				found = true;
-			}
-		}
-		hashMapIterator_destroy(importedServicesIterator);
-		celixThreadMutex_unlock(&manager->importedServicesLock);
-	}
-
-	if (found) {
-		status = topologyManager_removeImportedService(manager, endpoint, NULL);
-
-		if (status != CELIX_SUCCESS) {
-			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: Removal of imported service (%s; %s) failed.", endpoint->service, endpoint->id);
-		} else {
-			status = topologyManager_addImportedService(manager, endpoint, NULL);
-		}
-	}
-	return status;
-}
-
-celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
-	celix_status_t status = CELIX_SUCCESS;
-	topology_manager_pt manager = handle;
-
-	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add imported service (%s; %s).", endpoint->service, endpoint->id);
-
-	if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
-
-		hash_map_pt imports = hashMap_create(NULL, NULL, NULL, NULL);
-		hashMap_put(manager->importedServices, endpoint, imports);
-
-		if (scope_allowImport(manager->scope, endpoint)) {
-			if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
-				int size = arrayList_size(manager->rsaList);
-
-				for (int iter = 0; iter < size; iter++) {
-					import_registration_pt import = NULL;
-					remote_service_admin_service_pt rsa = arrayList_get(manager->rsaList, iter);
-					celix_status_t substatus = rsa->importService(rsa->admin, endpoint, &import);
-					if (substatus == CELIX_SUCCESS) {
-						hashMap_put(imports, rsa, import);
-					} else {
-						status = substatus;
-					}
-				}
-				celixThreadMutex_unlock(&manager->rsaListLock);
-			}
-
-		}
-
-		celixThreadMutex_unlock(&manager->importedServicesLock);
-	}
-
-
-	return status;
-}
-
-celix_status_t topologyManager_removeImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
-	celix_status_t status = CELIX_SUCCESS;
-	topology_manager_pt manager = handle;
-
-	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", endpoint->service, endpoint->id);
-
-	if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
-
-		hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
-		while (hashMapIterator_hasNext(iter)) {
-			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-			endpoint_description_pt ep = hashMapEntry_getKey(entry);
-			hash_map_pt imports = hashMapEntry_getValue(entry);
-
-			if (imports != NULL && strcmp(endpoint->id, ep->id) == 0) {
-				hash_map_iterator_pt importsIter = hashMapIterator_create(imports);
-
-				while (hashMapIterator_hasNext(importsIter)) {
-					hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter);
-					remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
-					import_registration_pt import = hashMapEntry_getValue(entry);
-					celix_status_t substatus = rsa->importRegistration_close(rsa->admin, import);
-					if (substatus == CELIX_SUCCESS) {
-						hashMapIterator_remove(importsIter);
-					} else {
-						status = substatus;
-					}
-				}
-				hashMapIterator_destroy(importsIter);
-				hashMapIterator_remove(iter);
-
-				hashMap_destroy(imports, false, false);
-			}
-		}
-		hashMapIterator_destroy(iter);
-		celixThreadMutex_unlock(&manager->importedServicesLock);
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_addExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) {
-	celix_status_t status = CELIX_SUCCESS;
-	properties_pt serviceProperties = NULL;
-
-	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add exported service (%s).", serviceId);
-
-	if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
-		scope_getExportProperties(manager->scope, reference, &serviceProperties);
-		hash_map_pt exports = hashMap_create(NULL, NULL, NULL, NULL);
-		hashMap_put(manager->exportedServices, reference, exports);
-
-		if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
-			int size = arrayList_size(manager->rsaList);
-
-			if (size == 0) {
-				logHelper_log(manager->loghelper, OSGI_LOGSERVICE_WARNING, "TOPOLOGY_MANAGER: No RSA available yet.");
-			}
-
-			for (int iter = 0; iter < size; iter++) {
-				remote_service_admin_service_pt rsa = arrayList_get(manager->rsaList, iter);
-
-				array_list_pt endpoints = NULL;
-				celix_status_t substatus = rsa->exportService(rsa->admin, serviceId, serviceProperties, &endpoints);
-
-				if (substatus == CELIX_SUCCESS) {
-					hashMap_put(exports, rsa, endpoints);
-					topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints);
-				} else {
-					status = substatus;
-				}
-			}
-			celixThreadMutex_unlock(&manager->rsaListLock);
-		}
-		celixThreadMutex_unlock(&manager->exportedServicesLock);
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_removeExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove exported service (%s).", serviceId);
-
-	if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
-		hash_map_pt exports = hashMap_get(manager->exportedServices, reference);
-		if (exports) {
-			hash_map_iterator_pt iter = hashMapIterator_create(exports);
-			while (hashMapIterator_hasNext(iter)) {
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-				remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
-				array_list_pt exportRegistrations = hashMapEntry_getValue(entry);
-
-				int size = arrayList_size(exportRegistrations);
-
-				for (int exportsIter = 0; exportsIter < size; exportsIter++) {
-					export_registration_pt export = arrayList_get(exportRegistrations, exportsIter);
-					topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
-					rsa->exportRegistration_close(rsa->admin, export);
-				}
-
-				hashMap_remove(exports, rsa);
-				//arrayList_destroy(exportRegistrations);
-				hashMapIterator_destroy(iter);
-				iter = hashMapIterator_create(exports);
-
-			}
-			hashMapIterator_destroy(iter);
-		}
-		exports = hashMap_remove(manager->exportedServices, reference);
-
-		if (exports != NULL) {
-			hashMap_destroy(exports, false, false);
-		}
-
-		celixThreadMutex_unlock(&manager->exportedServicesLock);
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_getEndpointDescriptionForExportRegistration(remote_service_admin_service_pt rsa, export_registration_pt export, endpoint_description_pt *endpoint) {
-	celix_status_t status;
-
-	export_reference_pt reference = NULL;
-	status = rsa->exportRegistration_getExportReference(export, &reference);
-
-	if (status == CELIX_SUCCESS) {
-		status = rsa->exportReference_getExportedEndpoint(reference, endpoint);
-	}
-
-	free(reference);
-
-	return status;
-}
-
-celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service) {
-	celix_status_t status = CELIX_SUCCESS;
-	topology_manager_pt manager = (topology_manager_pt) handle;
-
-	bundleContext_getService(manager->context, reference, service);
-
-	return status;
-}
-
-celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) {
-	celix_status_t status = CELIX_SUCCESS;
-	topology_manager_pt manager = handle;
-	const char* scope = NULL;
-
-	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added ENDPOINT_LISTENER");
-
-	if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
-		hashMap_put(manager->listenerList, reference, NULL);
-		celixThreadMutex_unlock(&manager->listenerListLock);
-
-		serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
-		filter_pt filter = filter_create(scope);
-		hash_map_iterator_pt refIter = hashMapIterator_create(manager->exportedServices);
-
-		while (hashMapIterator_hasNext(refIter)) {
-			hash_map_pt rsaExports = hashMapIterator_nextValue(refIter);
-			hash_map_iterator_pt rsaIter = hashMapIterator_create(rsaExports);
-
-			while (hashMapIterator_hasNext(rsaIter)) {
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(rsaIter);
-				remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
-				array_list_pt registrations = hashMapEntry_getValue(entry);
-
-				int arrayListSize = arrayList_size(registrations);
-				int cnt = 0;
-
-				for (; cnt < arrayListSize; cnt++) {
-					export_registration_pt export = arrayList_get(registrations, cnt);
-					endpoint_description_pt endpoint = NULL;
-
-					status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
-					if (status == CELIX_SUCCESS) {
-						bool matchResult = false;
-						filter_match(filter, endpoint->properties, &matchResult);
-						if (matchResult) {
-							endpoint_listener_pt listener = (endpoint_listener_pt) service;
-							status = listener->endpointAdded(listener->handle, endpoint, (char*)scope);
-						}
-					}
-				}
-			}
-			hashMapIterator_destroy(rsaIter);
-		}
-		hashMapIterator_destroy(refIter);
-
-		filter_destroy(filter);
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status;
-
-	status = topologyManager_endpointListenerRemoved(handle, reference, service);
-
-	if (status == CELIX_SUCCESS) {
-		status = topologyManager_endpointListenerAdded(handle, reference, service);
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-	topology_manager_pt manager = handle;
-
-	if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
-
-		if (hashMap_remove(manager->listenerList, reference)) {
-			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
-		}
-
-		celixThreadMutex_unlock(&manager->listenerListLock);
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
-
-		hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList);
-		while (hashMapIterator_hasNext(iter)) {
-			const char* scope = NULL;
-			endpoint_listener_pt epl = NULL;
-			service_reference_pt reference = hashMapIterator_nextKey(iter);
-
-			serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
-			status = bundleContext_getService(manager->context, reference, (void **) &epl);
-			if (status == CELIX_SUCCESS) {
-				filter_pt filter = filter_create(scope);
-
-				int regSize = arrayList_size(registrations);
-				for (int regIt = 0; regIt < regSize; regIt++) {
-					export_registration_pt export = arrayList_get(registrations, regIt);
-					endpoint_description_pt endpoint = NULL;
-					celix_status_t substatus = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
-					if (substatus == CELIX_SUCCESS) {
-						bool matchResult = false;
-						filter_match(filter, endpoint->properties, &matchResult);
-						if (matchResult) {
-							status = epl->endpointAdded(epl->handle, endpoint, (char*)scope);
-						}
-					} else {
-						status = substatus;
-					}
-				}
-				filter_destroy(filter);
-			}
-		}
-		hashMapIterator_destroy(iter);
-		celixThreadMutex_unlock(&manager->listenerListLock);
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
-		hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList);
-		while (hashMapIterator_hasNext(iter)) {
-			endpoint_description_pt endpoint = NULL;
-			endpoint_listener_pt epl = NULL;
-			celix_status_t substatus;
-			const char* scope = NULL;
-
-			service_reference_pt reference = hashMapIterator_nextKey(iter);
-			serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
-			substatus = bundleContext_getService(manager->context, reference, (void **) &epl);
-
-			if (substatus == CELIX_SUCCESS) {
-				substatus = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
-			}
-
-			if (substatus == CELIX_SUCCESS) {
-				substatus = epl->endpointRemoved(epl->handle, endpoint, NULL);
-			}
-
-			/*            if (substatus != CELIX_SUCCESS) {
-             status = substatus;
-
-             }
-			 */
-		}
-		hashMapIterator_destroy(iter);
-		celixThreadMutex_unlock(&manager->listenerListLock);
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_extendFilter(topology_manager_pt manager, char *filter, char **updatedFilter) {
-	celix_status_t status;
-	bundle_context_pt context = manager->context;
-	const char* uuid = NULL;
-
-	status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-
-	if (!uuid) {
-		logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!");
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	int len = 10 + strlen(filter) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
-	*updatedFilter = malloc(len);
-	if (!*updatedFilter) {
-		return CELIX_ENOMEM;
-	}
-
-	snprintf(*updatedFilter, len, "(&%s(!(%s=%s)))", filter, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
-
-	return status;
-}
-
-celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt listeners) {
-	celix_status_t status = CELIX_SUCCESS;
-	topology_manager_pt manager = handle;
-
-	for (int i = 0; i < arrayList_size(listeners); i++) {
-		listener_hook_info_pt info = arrayList_get(listeners, i);
-		bundle_pt bundle = NULL, self = NULL;
-		bundleContext_getBundle(info->context, &bundle);
-		bundleContext_getBundle(manager->context, &self);
-		if (bundle == self) {
-			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself.");
-			continue;
-		}
-
-		logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" added", info->filter);
-
-		char *filter = NULL;
-		bool free_filter = true;
-		status = topologyManager_extendFilter(manager, info->filter, &filter);
-#if 0
-		if(filter != NULL){
-			// TODO: add status handling
-			status = celixThreadMutex_lock(&manager->importScopesLock);
-
-			struct scope *interest = hashMap_get(manager->importScopes, filter);
-			if (interest) {
-				interest->refs++;
-				free(filter);
-				filter = NULL;
-			} else {
-				interest = malloc(sizeof(*interest));
-				interest->filter = filter;
-				interest->refs = 1;
-				hashMap_put(manager->importScopes, filter, interest);
-				free_filter = false;
-			}
-
-			status = celixThreadMutex_unlock(&manager->importScopesLock);
-		}
-#endif
-
-		if (filter != NULL && free_filter) {
-			free(filter);
-		}
-
-	}
-
-	return status;
-}
-
-celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt listeners) {
-	celix_status_t status = CELIX_SUCCESS;
-	topology_manager_pt manager = handle;
-
-	for (int i = 0; i < arrayList_size(listeners); i++) {
-		listener_hook_info_pt info = arrayList_get(listeners, i);
-
-		bundle_pt bundle = NULL, self = NULL;
-		bundleContext_getBundle(info->context, &bundle);
-		bundleContext_getBundle(manager->context, &self);
-		if (bundle == self) {
-			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself.");
-			continue;
-		}
-
-		logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" removed.", info->filter);
-
-		char *filter = NULL;
-		topologyManager_extendFilter(manager, info->filter, &filter);
-#if 0
-		status = celixThreadMutex_lock(&manager->importScopesLock);
-
-		struct scope *interest = hashMap_get(manager->importScopes, filter);
-		if (interest != NULL && --interest->refs <= 0) {
-			// last reference, remove from scope
-			hash_map_entry_pt entry = hashMap_getEntry(manager->importScopes, filter);
-			char* key = (char*) hashMapEntry_getKey(entry);
-			interest = hashMap_remove(manager->importScopes, filter);
-			free(key);
-			free(interest);
-		}
-#endif
-
-		if (filter != NULL) {
-			free(filter);
-		}
-#if 0
-		status = celixThreadMutex_unlock(&manager->importScopesLock);
-#endif
-	}
-
-	return status;
-}
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/public/include/tm_scope.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/public/include/tm_scope.h b/remote_services/topology_manager/public/include/tm_scope.h
deleted file mode 100644
index d4f60ca..0000000
--- a/remote_services/topology_manager/public/include/tm_scope.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * tm_scope.h
- *
- *  \date       Oct 29, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef TM_SCOPE_H_
-#define TM_SCOPE_H_
-
-#include "celix_errno.h"
-
-#define TOPOLOGYMANAGER_SCOPE_SERVICE "tm_scope"
-
-
-struct tm_scope_service {
-    void *handle;	// scope_pt
-    celix_status_t (*addExportScope)(void *handle, char *filter, properties_pt props);
-    celix_status_t (*removeExportScope)(void *handle, char *filter);
-    celix_status_t (*addImportScope)(void *handle, char *filter);
-    celix_status_t (*removeImportScope)(void *handle, char *filter);
-};
-
-typedef struct tm_scope_service tm_scope_service_t;
-typedef tm_scope_service_t *tm_scope_service_pt;
-
-#endif /* TM_SCOPE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/activator.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/activator.c b/remote_services/topology_manager/src/activator.c
new file mode 100644
index 0000000..7f39a25
--- /dev/null
+++ b/remote_services/topology_manager/src/activator.c
@@ -0,0 +1,289 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * activator.c
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "constants.h"
+#include "bundle_activator.h"
+#include "service_tracker.h"
+#include "service_registration.h"
+
+#include "topology_manager.h"
+#include "endpoint_listener.h"
+#include "remote_constants.h"
+#include "listener_hook_service.h"
+#include "log_service.h"
+#include "log_helper.h"
+#include "scope.h"
+#include "tm_scope.h"
+#include "topology_manager.h"
+
+struct activator {
+	bundle_context_pt context;
+
+	topology_manager_pt manager;
+
+	service_tracker_pt endpointListenerTracker;
+	service_tracker_pt remoteServiceAdminTracker;
+	service_listener_pt serviceListener;
+
+	endpoint_listener_pt endpointListener;
+	service_registration_pt endpointListenerService;
+
+	listener_hook_service_pt hookService;
+	service_registration_pt hook;
+
+	tm_scope_service_pt	scopeService;
+	service_registration_pt scopeReg;
+
+	log_helper_pt loghelper;
+};
+
+
+static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker);
+static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker);
+static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener);
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = NULL;
+	void *scope;
+
+	activator = calloc(1, sizeof(struct activator));
+
+	if (!activator) {
+		return CELIX_ENOMEM;
+	}
+
+	activator->context = context;
+	activator->endpointListenerService = NULL;
+	activator->endpointListenerTracker = NULL;
+	activator->hook = NULL;
+	activator->manager = NULL;
+	activator->remoteServiceAdminTracker = NULL;
+	activator->serviceListener = NULL;
+	activator->scopeService = calloc(1, sizeof(*(activator->scopeService)));
+	if (activator->scopeService == NULL)
+	{
+		free(activator);
+		return CELIX_ENOMEM;
+	}
+
+	activator->scopeService->addExportScope = tm_addExportScope;
+	activator->scopeService->removeExportScope = tm_removeExportScope;
+	activator->scopeService->addImportScope = tm_addImportScope;
+	activator->scopeService->removeImportScope = tm_removeImportScope;
+	activator->scopeReg = NULL; // explicitly needed, otherwise exception
+
+	logHelper_create(context, &activator->loghelper);
+	logHelper_start(activator->loghelper);
+
+	status = topologyManager_create(context, activator->loghelper, &activator->manager, &scope);
+	activator->scopeService->handle = scope;
+
+	if (status == CELIX_SUCCESS) {
+		status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
+		if (status == CELIX_SUCCESS) {
+			status = bundleActivator_createRSATracker(activator, &activator->remoteServiceAdminTracker);
+			if (status == CELIX_SUCCESS) {
+				status = bundleActivator_createServiceListener(activator, &activator->serviceListener);
+				if (status == CELIX_SUCCESS) {
+					*userData = activator;
+				}
+			}
+		}
+	}
+
+	if(status != CELIX_SUCCESS){
+		bundleActivator_destroy(activator,context);
+	}
+
+	return status;
+}
+
+static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) {
+	celix_status_t status;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(activator->manager, topologyManager_endpointListenerAdding, topologyManager_endpointListenerAdded, topologyManager_endpointListenerModified,
+			topologyManager_endpointListenerRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker);
+	}
+
+	return status;
+}
+
+static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker) {
+	celix_status_t status;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(activator->manager, topologyManager_rsaAdding, topologyManager_rsaAdded, topologyManager_rsaModified, topologyManager_rsaRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(activator->context, OSGI_RSA_REMOTE_SERVICE_ADMIN, customizer, tracker);
+	}
+
+	return status;
+}
+
+static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*listener = malloc(sizeof(**listener));
+	if (!*listener) {
+		return CELIX_ENOMEM;
+	}
+
+	(*listener)->handle = activator->manager;
+	(*listener)->serviceChanged = topologyManager_serviceChanged;
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status;
+	struct activator *activator = userData;
+
+	endpoint_listener_pt endpointListener = malloc(sizeof(*endpointListener));
+	endpointListener->handle = activator->manager;
+	endpointListener->endpointAdded = topologyManager_addImportedService;
+	endpointListener->endpointRemoved = topologyManager_removeImportedService;
+	activator->endpointListener = endpointListener;
+
+	const char *uuid = NULL;
+	status = bundleContext_getProperty(activator->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+	if (!uuid) {
+		logHelper_log(activator->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!");
+		return CELIX_ILLEGAL_STATE;
+	}
+
+	size_t len = 14 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
+	char *scope = malloc(len);
+	if (!scope) {
+		return CELIX_ENOMEM;
+	}
+
+	snprintf(scope, len, "(&(%s=*)(!(%s=%s)))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+
+	logHelper_log(activator->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: endpoint listener scope is %s", scope);
+
+	properties_pt props = properties_create();
+	properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
+
+	// We can release the scope, as properties_set makes a copy of the key & value...
+	free(scope);
+
+	bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService);
+
+	listener_hook_service_pt hookService = malloc(sizeof(*hookService));
+	hookService->handle = activator->manager;
+	hookService->added = topologyManager_listenerAdded;
+	hookService->removed = topologyManager_listenerRemoved;
+	activator->hookService = hookService;
+
+	bundleContext_registerService(context, (char *) OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, hookService, NULL, &activator->hook);
+	bundleContext_addServiceListener(context, activator->serviceListener, "(service.exported.interfaces=*)");
+
+	if (status == CELIX_SUCCESS) {
+		serviceTracker_open(activator->remoteServiceAdminTracker);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_open(activator->endpointListenerTracker);
+	}
+
+	bundleContext_registerService(context, (char *) TOPOLOGYMANAGER_SCOPE_SERVICE, activator->scopeService, NULL, &activator->scopeReg);
+
+	array_list_pt references = NULL;
+	bundleContext_getServiceReferences(context, NULL, "(service.exported.interfaces=*)", &references);
+	int i;
+	for (i = 0; i < arrayList_size(references); i++) {
+		service_reference_pt reference = arrayList_get(references, i);
+		const char* serviceId = NULL;
+		status = CELIX_DO_IF(status, serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId));
+
+		CELIX_DO_IF(status, topologyManager_addExportedService(activator->manager, reference, (char*)serviceId));
+	}
+	arrayList_destroy(references);
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	if (serviceTracker_close(activator->remoteServiceAdminTracker) == CELIX_SUCCESS) {
+		serviceTracker_destroy(activator->remoteServiceAdminTracker);
+	}
+
+	if (serviceTracker_close(activator->endpointListenerTracker) == CELIX_SUCCESS) {
+		serviceTracker_destroy(activator->endpointListenerTracker);
+	}
+
+	bundleContext_removeServiceListener(context, activator->serviceListener);
+	free(activator->serviceListener);
+
+	serviceRegistration_unregister(activator->hook);
+	free(activator->hookService);
+
+	serviceRegistration_unregister(activator->endpointListenerService);
+	free(activator->endpointListener);
+
+	serviceRegistration_unregister(activator->scopeReg);
+
+	topologyManager_closeImports(activator->manager);
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	struct activator *activator = userData;
+	if (!activator || !activator->manager) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	} else {
+		logHelper_stop(activator->loghelper);
+		logHelper_destroy(&activator->loghelper);
+
+		status = topologyManager_destroy(activator->manager);
+
+		if (activator->scopeService) {
+			free(activator->scopeService);
+		}
+
+		free(activator);
+	}
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/scope.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/scope.c b/remote_services/topology_manager/src/scope.c
new file mode 100644
index 0000000..b81d050
--- /dev/null
+++ b/remote_services/topology_manager/src/scope.c
@@ -0,0 +1,326 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * scope.c
+ *
+ *  \date       Sep 29, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "scope.h"
+#include "tm_scope.h"
+#include "topology_manager.h"
+#include "utils.h"
+
+struct scope_item {
+    properties_pt props;
+};
+
+struct scope {
+    void *manager;	// owner of the scope datastructure
+    celix_thread_mutex_t exportScopeLock;
+    hash_map_pt exportScopes;           // key is filter, value is scope_item (properties set)
+
+    celix_thread_mutex_t importScopeLock;
+    array_list_pt importScopes;			// list of filters
+
+    celix_status_t (*exportScopeChangedHandler)(void* manager, char *filter);
+    celix_status_t (*importScopeChangedHandler)(void* manager, char *filter);
+};
+
+static celix_status_t import_equal(const void *, const void *, bool *equals);
+
+/*
+ * SERVICES
+ */
+
+celix_status_t tm_addExportScope(void *handle, char *filter, properties_pt props) {
+    celix_status_t status = CELIX_SUCCESS;
+    scope_pt scope = (scope_pt) handle;
+    properties_pt present;
+
+    if (handle == NULL)
+        return CELIX_ILLEGAL_ARGUMENT;
+
+    if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
+        // For now we just don't allow two exactly the same filters
+        // TODO: What we actually need is the following
+        // If part of the new filter is already present in any of the filters in exportScopes
+        // we have to assure that the new filter defines other property keys than the property keys
+        // in the already defined filter!
+        present = (properties_pt) hashMap_get(scope->exportScopes, filter);
+        if (present == NULL) {
+            struct scope_item *item = calloc(1, sizeof(*item));
+            if (item == NULL) {
+                status = CELIX_ENOMEM;
+            } else {
+                item->props = props;
+                hashMap_put(scope->exportScopes, (void*) strdup(filter), (void*) item);
+            }
+        } else {
+            // don't allow the same filter twice
+            properties_destroy(props);
+            status = CELIX_ILLEGAL_ARGUMENT;
+        }
+        celixThreadMutex_unlock(&scope->exportScopeLock);
+    }
+
+    if (scope->exportScopeChangedHandler != NULL) {
+        status = CELIX_DO_IF(status, scope->exportScopeChangedHandler(scope->manager, filter));
+    }
+
+    return status;
+}
+
+celix_status_t tm_removeExportScope(void *handle, char *filter) {
+    celix_status_t status = CELIX_SUCCESS;
+    scope_pt scope = (scope_pt) handle;
+
+    if (handle == NULL)
+        return CELIX_ILLEGAL_ARGUMENT;
+
+    if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
+        struct scope_item *present = (struct scope_item *) hashMap_get(scope->exportScopes, filter);
+        if (present == NULL) {
+            status = CELIX_ILLEGAL_ARGUMENT;
+        } else {
+            properties_destroy(present->props);
+            hashMap_remove(scope->exportScopes, filter); // frees also the item!
+        }
+        celixThreadMutex_unlock(&scope->exportScopeLock);
+    }
+    if (scope->exportScopeChangedHandler != NULL) {
+        status = CELIX_DO_IF(status, scope->exportScopeChangedHandler(scope->manager, filter));
+    }
+    return status;
+}
+
+celix_status_t tm_addImportScope(void *handle, char *filter) {
+    celix_status_t status = CELIX_SUCCESS;
+    scope_pt scope = (scope_pt) handle;
+
+    filter_pt new;
+
+    if (handle == NULL)
+        return CELIX_ILLEGAL_ARGUMENT;
+    new = filter_create(filter);
+    if (new == NULL) {
+        return CELIX_ILLEGAL_ARGUMENT; // filter not parseble
+    }
+    if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
+        int index = arrayList_indexOf(scope->importScopes, new);
+        filter_pt present = (filter_pt) arrayList_get(scope->importScopes, index);
+        if (present == NULL) {
+            arrayList_add(scope->importScopes, new);
+        } else {
+            filter_destroy(new);
+            status = CELIX_ILLEGAL_ARGUMENT;
+        }
+
+        celixThreadMutex_unlock(&scope->importScopeLock);
+    }
+    if (scope->importScopeChangedHandler != NULL) {
+        status = CELIX_DO_IF(status, scope->importScopeChangedHandler(scope->manager, filter));
+    }
+    return status;
+}
+
+celix_status_t tm_removeImportScope(void *handle, char *filter) {
+    celix_status_t status = CELIX_SUCCESS;
+    scope_pt scope = (scope_pt) handle;
+    filter_pt new;
+
+    if (handle == NULL)
+        return CELIX_ILLEGAL_ARGUMENT;
+
+    new = filter_create(filter);
+    if (new == NULL) {
+        return CELIX_ILLEGAL_ARGUMENT; // filter not parseble
+    }
+
+    if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
+        int index = arrayList_indexOf(scope->importScopes, new);
+        filter_pt present = (filter_pt) arrayList_get(scope->importScopes, index);
+        if (present == NULL)
+            status = CELIX_ILLEGAL_ARGUMENT;
+        else {
+            arrayList_removeElement(scope->importScopes, present);
+            filter_destroy(present);
+        }
+        celixThreadMutex_unlock(&scope->importScopeLock);
+    }
+    if (scope->importScopeChangedHandler != NULL) {
+        status = CELIX_DO_IF(status, scope->importScopeChangedHandler(scope->manager, filter));
+    }
+    filter_destroy(new);
+    return status;
+}
+
+/*****************************************************************************
+ * GLOBAL FUNCTIONS
+ *****************************************************************************/
+
+void scope_setExportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName)) {
+    scope->exportScopeChangedHandler = changed;
+}
+
+void scope_setImportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName)) {
+    scope->importScopeChangedHandler = changed;
+}
+
+celix_status_t scope_scopeCreate(void *handle, scope_pt *scope) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *scope = calloc(1, sizeof **scope);
+
+    if (*scope == NULL) {
+        return CELIX_ENOMEM;
+    }
+
+    (*scope)->manager = handle;
+    celixThreadMutex_create(&(*scope)->exportScopeLock, NULL);
+    celixThreadMutex_create(&(*scope)->importScopeLock, NULL);
+
+    (*scope)->exportScopes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+    arrayList_createWithEquals(import_equal, &((*scope)->importScopes));
+    (*scope)->exportScopeChangedHandler = NULL;
+
+    return status;
+}
+
+celix_status_t scope_scopeDestroy(scope_pt scope) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
+        hash_map_iterator_pt iter = hashMapIterator_create(scope->exportScopes);
+        while (hashMapIterator_hasNext(iter)) {
+            hash_map_entry_pt scopedEntry = hashMapIterator_nextEntry(iter);
+            struct scope_item *item = (struct scope_item*) hashMapEntry_getValue(scopedEntry);
+            properties_destroy(item->props);
+        }
+        hashMapIterator_destroy(iter);
+        hashMap_destroy(scope->exportScopes, true, true); // free keys, free values
+        celixThreadMutex_unlock(&scope->exportScopeLock);
+    }
+
+    if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
+        array_list_iterator_pt imp_iter = arrayListIterator_create(scope->importScopes);
+        while (arrayListIterator_hasNext(imp_iter)) {
+            filter_pt element = (filter_pt) arrayListIterator_next(imp_iter);
+            filter_destroy(element);
+            // no need to call arrayList_removeElement(element) because complete list is destroyed
+        }
+        arrayListIterator_destroy(imp_iter);
+        arrayList_destroy(scope->importScopes);
+        celixThreadMutex_unlock(&scope->importScopeLock);
+    }
+
+    celixThreadMutex_destroy(&scope->exportScopeLock);
+    celixThreadMutex_destroy(&scope->importScopeLock);
+    free(scope);
+    return status;
+}
+
+/*****************************************************************************
+ * STATIC FUNCTIONS
+ *****************************************************************************/
+static celix_status_t import_equal(const void *src, const void *dest, bool *equals) {
+    celix_status_t status;
+
+    filter_pt src_filter = (filter_pt) src;
+    filter_pt dest_filter = (filter_pt) dest;
+    status = filter_match_filter(src_filter, dest_filter, equals);
+    return status;
+}
+
+bool scope_allowImport(scope_pt scope, endpoint_description_pt endpoint) {
+    bool allowImport = false;
+    array_list_iterator_pt iter;
+
+    if (celixThreadMutex_lock(&(scope->importScopeLock)) == CELIX_SUCCESS) {
+        if (arrayList_size(scope->importScopes) == 0) {
+            allowImport = true;
+        } else {
+            iter = arrayListIterator_create(scope->importScopes);
+            while ((allowImport == false) && arrayListIterator_hasNext(iter)) {
+                filter_pt element = (filter_pt) arrayListIterator_next(iter);
+                filter_match(element, endpoint->properties, &allowImport);
+            }
+            arrayListIterator_destroy(iter);
+        }
+        celixThreadMutex_unlock(&scope->importScopeLock);
+    }
+    return allowImport;
+}
+
+celix_status_t scope_getExportProperties(scope_pt scope, service_reference_pt reference, properties_pt *props) {
+    celix_status_t status = CELIX_SUCCESS;
+    unsigned int size = 0;
+    char **keys;
+    bool found = false;
+
+    *props = NULL;
+    properties_pt serviceProperties = properties_create();  // GB: not sure if a copy is needed
+                                                            // or serviceReference_getProperties() is
+                                                            // is acceptable
+
+    serviceReference_getPropertyKeys(reference, &keys, &size);
+    for (int i = 0; i < size; i++) {
+        char *key = keys[i];
+        const char* value = NULL;
+
+        if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS) {
+//        		&& strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
+//        		&& strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
+            properties_set(serviceProperties, key, value);
+        }
+
+    }
+
+    free(keys);
+
+    if (celixThreadMutex_lock(&(scope->exportScopeLock)) == CELIX_SUCCESS) {
+        hash_map_iterator_pt scopedPropIter = hashMapIterator_create(scope->exportScopes);
+        // TODO: now stopping if first filter matches, alternatively we could build up
+        //       the additional output properties for each filter that matches?
+        while ((!found) && hashMapIterator_hasNext(scopedPropIter)) {
+            hash_map_entry_pt scopedEntry = hashMapIterator_nextEntry(scopedPropIter);
+            char *filterStr = (char *) hashMapEntry_getKey(scopedEntry);
+            filter_pt filter = filter_create(filterStr);
+            if (filter != NULL) {
+                // test if the scope filter matches the exported service properties
+                status = filter_match(filter, serviceProperties, &found);
+                if (found) {
+                    struct scope_item *item = (struct scope_item *) hashMapEntry_getValue(scopedEntry);
+                    *props = item->props;
+                }
+            }
+            filter_destroy(filter);
+        }
+        hashMapIterator_destroy(scopedPropIter);
+        properties_destroy(serviceProperties);
+
+        celixThreadMutex_unlock(&(scope->exportScopeLock));
+    }
+
+    return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/scope.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/scope.h b/remote_services/topology_manager/src/scope.h
new file mode 100644
index 0000000..4035e2c
--- /dev/null
+++ b/remote_services/topology_manager/src/scope.h
@@ -0,0 +1,150 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * scope.h
+ *
+ *  \date       Sep 29, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef TOPOLOGY_SCOPE_H_
+#define TOPOLOGY_SCOPE_H_
+
+#include "celixbool.h"
+#include "celix_errno.h"
+#include "celix_threads.h"
+#include "hash_map.h"
+#include "endpoint_description.h"
+#include "properties.h"
+#include "service_reference.h"
+#include "tm_scope.h"
+
+typedef struct scope *scope_pt;
+
+
+
+/* \brief  create scope structure
+ *
+ * \param  owning component pointer
+ * \param  scope to be created
+ *
+ * \return CELIX_SUCCESS
+ *         CELIX_ENOMEM
+ */
+celix_status_t scope_scopeCreate(void *handle, scope_pt *scope);
+
+/* \brief  destroy scope structure
+ *
+ * \param  scope to be destroyed
+ *
+ * \return CELIX_SUCCESS
+ */
+celix_status_t scope_scopeDestroy(scope_pt scope);
+
+/* \brief  register export scope change callback of topology manager
+ *
+ * \param  scope structure
+ * \param  changed function pointer
+ *
+ * \return -
+ */
+void scope_setExportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName));
+
+/* \brief  register import scope change callback of topology manager
+ *
+ * \param  scope structure
+ * \param  changed function pointer
+ *
+ * \return -
+ */
+void scope_setImportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName));
+
+
+/* \brief  Test if scope allows import of service
+ *
+ * \param  scope containing import rules
+ * \param  endpoint import service endpoint description
+ *
+ * \return true import allowed
+ *         false import not allowed
+ */
+bool scope_allowImport(scope_pt scope, endpoint_description_pt endpoint);
+
+/* \brief  Test if scope allows import of service
+ *
+ * \param  scope containing export rules
+ * \param  reference to service
+ * \param  props, additional properties defining restrictions for the exported service
+ *                NULL if no additional restrictions found
+ *
+ * \return CELIX_SUCCESS
+ *
+ */
+celix_status_t scope_getExportProperties(scope_pt scope, service_reference_pt reference, properties_pt *props);
+
+/* \brief  add restricted scope for specified exported service
+ *
+ * \param  handle pointer to scope
+ * \param  filter, filter string
+ * \param  props additional properties defining restrictions for the exported service
+ *
+ * \return CELIX_SUCCESS if added to scope
+ *         CELIX_ILLEGAL_ARGUMENT if service scope is already restricted before
+ *
+ */
+celix_status_t tm_addExportScope(void *handle, char *filter, properties_pt props);
+
+/* \brief  remove restricted scope for specified exported service
+ *
+ * \param  handle pointer to scope
+ * \param  filter, filter string
+ *
+ * \return CELIX_SUCCESS if removed
+ *         CELIX_ILLEGAL_ARGUMENT if service not found in scope
+ *
+ */
+celix_status_t tm_removeExportScope(void *handle, char *filter);
+
+/* \brief  add restricted scope for specified imported service
+ *
+ * \param  handle pointer to scope
+ * \param  filter, filter string
+ * \param  props additional properties defining restrictions for the imported service
+ *
+ * \return CELIX_SUCCESS if added to scope
+ *         CELIX_ILLEGAL_ARGUMENT if service scope is already restricted before
+ *
+ */
+celix_status_t tm_addImportScope(void *handle, char *filter);
+
+
+/* \brief  remove restricted scope for specified imported service
+ *
+ * \param  handle pointer to scope
+ * \param  filter, filter string
+ *
+ * \return CELIX_SUCCESS if removed
+ *         CELIX_ILLEGAL_ARGUMENT if service not found in scope
+ *
+ */
+celix_status_t tm_removeImportScope(void *handle, char *filter);
+
+
+#endif // TOPOLOGY_SCOPE_H_


[16/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/CMakeLists.txt b/pubsub/pubsub_discovery/CMakeLists.txt
index 948da3e..0e7d6c5 100644
--- a/pubsub/pubsub_discovery/CMakeLists.txt
+++ b/pubsub/pubsub_discovery/CMakeLists.txt
@@ -18,26 +18,25 @@
 find_package(CURL REQUIRED)
 find_package(Jansson REQUIRED)
 
-include_directories("${CURL_INCLUDE_DIR}")
-include_directories("${JANSSON_INCLUDE_DIR}")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("${PROJECT_SOURCE_DIR}/etcdlib/public/include")
-include_directories("private/include")
-include_directories("public/include")
-
 add_bundle(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
     BUNDLE_SYMBOLICNAME "apache_celix_pubsub_discovery_etcd"
     VERSION "1.0.0"
     SOURCES
-		private/src/psd_activator.c
-		private/src/pubsub_discovery_impl.c
-		private/src/etcd_common.c
-		private/src/etcd_watcher.c
-		private/src/etcd_writer.c
+        src/psd_activator.c
+        src/pubsub_discovery_impl.c
+        src/etcd_common.c
+        src/etcd_watcher.c
+        src/etcd_writer.c
 		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
 		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
 )
 
-target_link_libraries(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery celix_framework celix_utils etcdlib_static ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
+target_include_directories(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery PRIVATE
+    src
+    include
+	${CURL_INCLUDE_DIR}
+	${JANSSON_INCLUDE_DIR}
+        )
+
+target_link_libraries(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery PRIVATE Celix::framework Celix::etcdlib_static ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
 install_bundle(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/include/etcd_common.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/include/etcd_common.h b/pubsub/pubsub_discovery/private/include/etcd_common.h
deleted file mode 100644
index 7a3e7b6..0000000
--- a/pubsub/pubsub_discovery/private/include/etcd_common.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef ETCD_COMMON_H_
-#define ETCD_COMMON_H_
-
-#include "bundle_context.h"
-#include "celix_errno.h"
-
-celix_status_t etcdCommon_init(bundle_context_pt context);
-
-#endif /* ETCD_COMMON_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/include/etcd_watcher.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/include/etcd_watcher.h b/pubsub/pubsub_discovery/private/include/etcd_watcher.h
deleted file mode 100644
index c425e60..0000000
--- a/pubsub/pubsub_discovery/private/include/etcd_watcher.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef ETCD_WATCHER_H_
-#define ETCD_WATCHER_H_
-
-#include "bundle_context.h"
-#include "celix_errno.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_endpoint.h"
-
-typedef struct etcd_watcher *etcd_watcher_pt;
-
-celix_status_t etcdWatcher_create(pubsub_discovery_pt discovery,  bundle_context_pt context, const char *scope, const char* topic, etcd_watcher_pt *watcher);
-celix_status_t etcdWatcher_destroy(etcd_watcher_pt watcher);
-celix_status_t etcdWatcher_stop(etcd_watcher_pt watcher);
-
-celix_status_t etcdWatcher_getPublisherEndpointFromKey(pubsub_discovery_pt discovery, const char* key, const char* value, pubsub_endpoint_pt* pubEP);
-
-
-#endif /* ETCD_WATCHER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/include/etcd_writer.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/include/etcd_writer.h b/pubsub/pubsub_discovery/private/include/etcd_writer.h
deleted file mode 100644
index 3ff98b9..0000000
--- a/pubsub/pubsub_discovery/private/include/etcd_writer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef ETCD_WRITER_H_
-#define ETCD_WRITER_H_
-
-#include "bundle_context.h"
-#include "celix_errno.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_endpoint.h"
-
-typedef struct etcd_writer *etcd_writer_pt;
-
-
-etcd_writer_pt etcdWriter_create(pubsub_discovery_pt discovery);
-void etcdWriter_destroy(etcd_writer_pt writer);
-
-celix_status_t etcdWriter_addPublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP,bool storeEP);
-celix_status_t etcdWriter_deletePublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP);
-
-
-#endif /* ETCD_WRITER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/include/pubsub_discovery_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/include/pubsub_discovery_impl.h b/pubsub/pubsub_discovery/private/include/pubsub_discovery_impl.h
deleted file mode 100644
index 676a6ab..0000000
--- a/pubsub/pubsub_discovery/private/include/pubsub_discovery_impl.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef PUBSUB_DISCOVERY_IMPL_H_
-#define PUBSUB_DISCOVERY_IMPL_H_
-
-#include "bundle_context.h"
-#include "service_reference.h"
-
-#include "etcd_watcher.h"
-#include "etcd_writer.h"
-#include "pubsub_endpoint.h"
-
-#define FREE_MEM(ptr) if(ptr) {free(ptr); ptr = NULL;}
-
-struct watcher_info {
-    etcd_watcher_pt watcher;
-    int nr_references;
-};
-
-struct pubsub_discovery {
-	bundle_context_pt context;
-
-	celix_thread_mutex_t discoveredPubsMutex;
-	hash_map_pt discoveredPubs; //<topic,List<pubsub_endpoint_pt>>
-
-	celix_thread_mutex_t listenerReferencesMutex;
-	hash_map_pt listenerReferences; //key=serviceReference, value=nop
-
-	celix_thread_mutex_t watchersMutex;
-	hash_map_pt watchers; //key = topicname, value = struct watcher_info
-
-	etcd_writer_pt writer;
-};
-
-
-celix_status_t pubsub_discovery_create(bundle_context_pt context, pubsub_discovery_pt* node_discovery);
-celix_status_t pubsub_discovery_destroy(pubsub_discovery_pt node_discovery);
-celix_status_t pubsub_discovery_start(pubsub_discovery_pt node_discovery);
-celix_status_t pubsub_discovery_stop(pubsub_discovery_pt node_discovery);
-
-celix_status_t pubsub_discovery_addNode(pubsub_discovery_pt node_discovery, pubsub_endpoint_pt pubEP);
-celix_status_t pubsub_discovery_removeNode(pubsub_discovery_pt node_discovery, pubsub_endpoint_pt pubEP);
-
-celix_status_t pubsub_discovery_tmPublisherAnnounceAdded(void * handle, service_reference_pt reference, void * service);
-celix_status_t pubsub_discovery_tmPublisherAnnounceModified(void * handle, service_reference_pt reference, void * service);
-celix_status_t pubsub_discovery_tmPublisherAnnounceRemoved(void * handle, service_reference_pt reference, void * service);
-
-celix_status_t pubsub_discovery_announcePublisher(void *handle, pubsub_endpoint_pt pubEP);
-celix_status_t pubsub_discovery_removePublisher(void *handle, pubsub_endpoint_pt pubEP);
-celix_status_t pubsub_discovery_interestedInTopic(void *handle, const char* scope, const char* topic);
-celix_status_t pubsub_discovery_uninterestedInTopic(void *handle, const char* scope, const char* topic);
-
-celix_status_t pubsub_discovery_informPublishersListeners(pubsub_discovery_pt discovery, pubsub_endpoint_pt endpoint, bool endpointAdded);
-
-#endif /* PUBSUB_DISCOVERY_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/etcd_common.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/etcd_common.c b/pubsub/pubsub_discovery/private/src/etcd_common.c
deleted file mode 100644
index c757801..0000000
--- a/pubsub/pubsub_discovery/private/src/etcd_common.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "celix_log.h"
-#include "constants.h"
-
-#include <curl/curl.h>
-#include "etcd.h"
-#include "etcd_watcher.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_discovery_impl.h"
-
-
-#define MAX_ROOTNODE_LENGTH		128
-#define MAX_LOCALNODE_LENGTH 	4096
-#define MAX_FIELD_LENGTH		128
-
-#define CFG_ETCD_SERVER_IP		"PUBSUB_DISCOVERY_ETCD_SERVER_IP"
-#define DEFAULT_ETCD_SERVER_IP	"127.0.0.1"
-
-#define CFG_ETCD_SERVER_PORT	"PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
-#define DEFAULT_ETCD_SERVER_PORT 2379
-
-// be careful - this should be higher than the curl timeout
-#define CFG_ETCD_TTL   "DISCOVERY_ETCD_TTL"
-#define DEFAULT_ETCD_TTL 30
-
-
-celix_status_t etcdCommon_init(bundle_context_pt context) {
-    celix_status_t status = CELIX_SUCCESS;
-    const char* etcd_server = NULL;
-    const char* etcd_port_string = NULL;
-    int etcd_port = 0;
-
-    if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_IP, &etcd_server) != CELIX_SUCCESS) || !etcd_server) {
-        etcd_server = DEFAULT_ETCD_SERVER_IP;
-    }
-
-    if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_PORT, &etcd_port_string) != CELIX_SUCCESS) || !etcd_port_string) {
-        etcd_port = DEFAULT_ETCD_SERVER_PORT;
-    } else {
-        char* endptr = NULL;
-        errno = 0;
-        etcd_port = strtol(etcd_port_string, &endptr, 10);
-        if (*endptr || errno != 0) {
-            etcd_port = DEFAULT_ETCD_SERVER_PORT;
-        }
-    }
-
-    printf("PSD: Using discovery HOST:PORT: %s:%i\n", etcd_server, etcd_port);
-
-    if (etcd_init(etcd_server, etcd_port, CURL_GLOBAL_DEFAULT) != 0) {
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        status = CELIX_SUCCESS;
-    }
-
-    return status;
-}
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/etcd_watcher.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/etcd_watcher.c b/pubsub/pubsub_discovery/private/src/etcd_watcher.c
deleted file mode 100644
index 3c3a5a8..0000000
--- a/pubsub/pubsub_discovery/private/src/etcd_watcher.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "celix_log.h"
-#include "constants.h"
-
-#include "etcd.h"
-#include "etcd_watcher.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_discovery_impl.h"
-
-
-
-#define MAX_ROOTNODE_LENGTH             128
-#define MAX_LOCALNODE_LENGTH            4096
-#define MAX_FIELD_LENGTH                128
-
-#define CFG_ETCD_ROOT_PATH              "PUBSUB_DISCOVERY_ETCD_ROOT_PATH"
-#define DEFAULT_ETCD_ROOTPATH           "pubsub/discovery"
-
-#define CFG_ETCD_SERVER_IP              "PUBSUB_DISCOVERY_ETCD_SERVER_IP"
-#define DEFAULT_ETCD_SERVER_IP          "127.0.0.1"
-
-#define CFG_ETCD_SERVER_PORT            "PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
-#define DEFAULT_ETCD_SERVER_PORT        2379
-
-// be careful - this should be higher than the curl timeout
-#define CFG_ETCD_TTL                    "DISCOVERY_ETCD_TTL"
-#define DEFAULT_ETCD_TTL                30
-
-
-struct etcd_watcher {
-	pubsub_discovery_pt pubsub_discovery;
-
-	celix_thread_mutex_t watcherLock;
-	celix_thread_t watcherThread;
-
-	char *scope;
-	char *topic;
-	volatile bool running;
-};
-
-struct etcd_writer {
-	pubsub_discovery_pt pubsub_discovery;
-	celix_thread_mutex_t localPubsLock;
-	array_list_pt localPubs;
-	volatile bool running;
-	celix_thread_t writerThread;
-};
-
-
-// note that the rootNode shouldn't have a leading slash
-static celix_status_t etcdWatcher_getTopicRootPath(bundle_context_pt context, const char *scope, const char *topic, char* rootNode, int rootNodeLen) {
-	celix_status_t status = CELIX_SUCCESS;
-	const char* rootPath = NULL;
-
-	if (((bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath)) != CELIX_SUCCESS) || (!rootPath)) {
-		snprintf(rootNode, rootNodeLen, "%s/%s/%s", DEFAULT_ETCD_ROOTPATH, scope, topic);
-	} else {
-		snprintf(rootNode, rootNodeLen, "%s/%s/%s", rootPath, scope, topic);
-	}
-
-	return status;
-}
-
-static celix_status_t etcdWatcher_getRootPath(bundle_context_pt context, char* rootNode) {
-	celix_status_t status = CELIX_SUCCESS;
-	const char* rootPath = NULL;
-
-	if (((bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath)) != CELIX_SUCCESS) || (!rootPath)) {
-		strncpy(rootNode, DEFAULT_ETCD_ROOTPATH, MAX_ROOTNODE_LENGTH);
-	} else {
-		strncpy(rootNode, rootPath, MAX_ROOTNODE_LENGTH);
-	}
-
-	return status;
-}
-
-
-static void add_node(const char *key, const char *value, void* arg) {
-	pubsub_discovery_pt ps_discovery = (pubsub_discovery_pt) arg;
-	pubsub_endpoint_pt pubEP = NULL;
-	celix_status_t status = etcdWatcher_getPublisherEndpointFromKey(ps_discovery, key, value, &pubEP);
-	if(!status && pubEP) {
-		pubsub_discovery_addNode(ps_discovery, pubEP);
-	}
-}
-
-static celix_status_t etcdWatcher_addAlreadyExistingPublishers(pubsub_discovery_pt ps_discovery, const char *rootPath, long long * highestModified) {
-	celix_status_t status = CELIX_SUCCESS;
-	if(etcd_get_directory(rootPath, add_node, ps_discovery, highestModified)) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-	return status;
-}
-
-// gets everything from provided key
-celix_status_t etcdWatcher_getPublisherEndpointFromKey(pubsub_discovery_pt pubsub_discovery, const char* etcdKey, const char* etcdValue, pubsub_endpoint_pt* pubEP) {
-
-	celix_status_t status = CELIX_SUCCESS;
-
-	char rootPath[MAX_ROOTNODE_LENGTH];
-	char *expr = NULL;
-	char scope[MAX_FIELD_LENGTH];
-	char topic[MAX_FIELD_LENGTH];
-	char fwUUID[MAX_FIELD_LENGTH];
-	char serviceId[MAX_FIELD_LENGTH];
-
-	memset(rootPath,0,MAX_ROOTNODE_LENGTH);
-	memset(topic,0,MAX_FIELD_LENGTH);
-	memset(fwUUID,0,MAX_FIELD_LENGTH);
-	memset(serviceId,0,MAX_FIELD_LENGTH);
-
-	etcdWatcher_getRootPath(pubsub_discovery->context, rootPath);
-
-	asprintf(&expr, "/%s/%%[^/]/%%[^/]/%%[^/]/%%[^/].*", rootPath);
-	if(expr) {
-		int foundItems = sscanf(etcdKey, expr, scope, topic, fwUUID, serviceId);
-		free(expr);
-		if (foundItems != 4) { // Could happen when a directory is removed, just don't process this.
-			status = CELIX_ILLEGAL_STATE;
-		}
-		else{
-			status = pubsubEndpoint_create(fwUUID,scope,topic,strtol(serviceId,NULL,10),etcdValue,NULL,pubEP);
-		}
-	}
-	return status;
-}
-
-/*
- * performs (blocking) etcd_watch calls to check for
- * changing discovery endpoint information within etcd.
- */
-static void* etcdWatcher_run(void* data) {
-	etcd_watcher_pt watcher = (etcd_watcher_pt) data;
-	time_t timeBeforeWatch = time(NULL);
-	char rootPath[MAX_ROOTNODE_LENGTH];
-	long long highestModified = 0;
-
-	pubsub_discovery_pt ps_discovery = watcher->pubsub_discovery;
-	bundle_context_pt context = ps_discovery->context;
-
-	memset(rootPath, 0, MAX_ROOTNODE_LENGTH);
-
-	//TODO: add topic to etcd key
-	etcdWatcher_getTopicRootPath(context, watcher->scope, watcher->topic, rootPath, MAX_ROOTNODE_LENGTH);
-	etcdWatcher_addAlreadyExistingPublishers(ps_discovery, rootPath, &highestModified);
-
-	while ((celixThreadMutex_lock(&watcher->watcherLock) == CELIX_SUCCESS) && watcher->running) {
-
-		char *rkey = NULL;
-		char *value = NULL;
-		char *preValue = NULL;
-		char *action = NULL;
-		long long modIndex;
-
-		celixThreadMutex_unlock(&watcher->watcherLock);
-
-		if (etcd_watch(rootPath, highestModified + 1, &action, &preValue, &value, &rkey, &modIndex) == 0 && action != NULL) {
-			pubsub_endpoint_pt pubEP = NULL;
-			if ((strcmp(action, "set") == 0) || (strcmp(action, "create") == 0)) {
-				if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, value, &pubEP) == CELIX_SUCCESS) {
-					pubsub_discovery_addNode(ps_discovery, pubEP);
-				}
-			} else if (strcmp(action, "delete") == 0) {
-				if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, preValue, &pubEP) == CELIX_SUCCESS) {
-					pubsub_discovery_removeNode(ps_discovery, pubEP);
-				}
-			} else if (strcmp(action, "expire") == 0) {
-				if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, preValue, &pubEP) == CELIX_SUCCESS) {
-					pubsub_discovery_removeNode(ps_discovery, pubEP);
-				}
-			} else if (strcmp(action, "update") == 0) {
-				if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, value, &pubEP) == CELIX_SUCCESS) {
-					pubsub_discovery_addNode(ps_discovery, pubEP);
-				}
-			} else {
-				fw_log(logger, OSGI_FRAMEWORK_LOG_INFO, "Unexpected action: %s", action);
-			}
-			highestModified = modIndex;
-		} else if (time(NULL) - timeBeforeWatch <= (DEFAULT_ETCD_TTL / 4)) {
-			sleep(DEFAULT_ETCD_TTL / 4);
-		}
-
-		FREE_MEM(action);
-		FREE_MEM(value);
-		FREE_MEM(preValue);
-		FREE_MEM(rkey);
-
-		/* prevent busy waiting, in case etcd_watch returns false */
-
-
-		if (time(NULL) - timeBeforeWatch > (DEFAULT_ETCD_TTL / 4)) {
-			timeBeforeWatch = time(NULL);
-		}
-
-	}
-
-	if (watcher->running == false) {
-		celixThreadMutex_unlock(&watcher->watcherLock);
-	}
-
-	return NULL;
-}
-
-celix_status_t etcdWatcher_create(pubsub_discovery_pt pubsub_discovery, bundle_context_pt context, const char *scope, const char *topic, etcd_watcher_pt *watcher) {
-	celix_status_t status = CELIX_SUCCESS;
-
-
-	if (pubsub_discovery == NULL) {
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	(*watcher) = calloc(1, sizeof(struct etcd_watcher));
-
-	if(*watcher == NULL){
-		return CELIX_ENOMEM;
-	}
-
-	(*watcher)->pubsub_discovery = pubsub_discovery;
-	(*watcher)->scope = strdup(scope);
-	(*watcher)->topic = strdup(topic);
-
-
-	celixThreadMutex_create(&(*watcher)->watcherLock, NULL);
-
-	celixThreadMutex_lock(&(*watcher)->watcherLock);
-
-	status = celixThread_create(&(*watcher)->watcherThread, NULL, etcdWatcher_run, *watcher);
-	if (status == CELIX_SUCCESS) {
-		(*watcher)->running = true;
-	}
-
-	celixThreadMutex_unlock(&(*watcher)->watcherLock);
-
-
-	return status;
-}
-
-celix_status_t etcdWatcher_destroy(etcd_watcher_pt watcher) {
-
-	celix_status_t status = CELIX_SUCCESS;
-
-	char rootPath[MAX_ROOTNODE_LENGTH];
-	etcdWatcher_getTopicRootPath(watcher->pubsub_discovery->context, watcher->scope, watcher->topic, rootPath, MAX_ROOTNODE_LENGTH);
-	celixThreadMutex_destroy(&(watcher->watcherLock));
-
-	free(watcher->scope);
-	free(watcher->topic);
-	free(watcher);
-
-	return status;
-}
-
-celix_status_t etcdWatcher_stop(etcd_watcher_pt watcher){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&(watcher->watcherLock));
-	watcher->running = false;
-	celixThreadMutex_unlock(&(watcher->watcherLock));
-
-	celixThread_join(watcher->watcherThread, NULL);
-
-	return status;
-
-}
-
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/etcd_writer.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/etcd_writer.c b/pubsub/pubsub_discovery/private/src/etcd_writer.c
deleted file mode 100644
index 1c423f3..0000000
--- a/pubsub/pubsub_discovery/private/src/etcd_writer.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "celix_log.h"
-#include "constants.h"
-
-#include "etcd.h"
-#include "etcd_writer.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_discovery_impl.h"
-
-#define MAX_ROOTNODE_LENGTH		128
-
-#define CFG_ETCD_ROOT_PATH		"PUBSUB_DISCOVERY_ETCD_ROOT_PATH"
-#define DEFAULT_ETCD_ROOTPATH	"pubsub/discovery"
-
-#define CFG_ETCD_SERVER_IP		"PUBSUB_DISCOVERY_ETCD_SERVER_IP"
-#define DEFAULT_ETCD_SERVER_IP	"127.0.0.1"
-
-#define CFG_ETCD_SERVER_PORT	"PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
-#define DEFAULT_ETCD_SERVER_PORT 2379
-
-// be careful - this should be higher than the curl timeout
-#define CFG_ETCD_TTL   "DISCOVERY_ETCD_TTL"
-#define DEFAULT_ETCD_TTL 30
-
-struct etcd_writer {
-	pubsub_discovery_pt pubsub_discovery;
-	celix_thread_mutex_t localPubsLock;
-	array_list_pt localPubs;
-	volatile bool running;
-	celix_thread_t writerThread;
-};
-
-
-static const char* etcdWriter_getRootPath(bundle_context_pt context);
-static void* etcdWriter_run(void* data);
-
-
-etcd_writer_pt etcdWriter_create(pubsub_discovery_pt disc) {
-	etcd_writer_pt writer = calloc(1, sizeof(*writer));
-	if(writer) {
-		celixThreadMutex_create(&writer->localPubsLock, NULL);
-		arrayList_create(&writer->localPubs);
-		writer->pubsub_discovery = disc;
-		writer->running = true;
-		celixThread_create(&writer->writerThread, NULL, etcdWriter_run, writer);
-	}
-	return writer;
-}
-
-void etcdWriter_destroy(etcd_writer_pt writer) {
-	char dir[MAX_ROOTNODE_LENGTH];
-	const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
-
-	writer->running = false;
-	celixThread_join(writer->writerThread, NULL);
-
-	celixThreadMutex_lock(&writer->localPubsLock);
-	for(int i = 0; i < arrayList_size(writer->localPubs); i++) {
-		pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(writer->localPubs,i);
-		memset(dir,0,MAX_ROOTNODE_LENGTH);
-		snprintf(dir,MAX_ROOTNODE_LENGTH,"%s/%s/%s/%s",rootPath,pubEP->scope,pubEP->topic,pubEP->frameworkUUID);
-		etcd_del(dir);
-		pubsubEndpoint_destroy(pubEP);
-	}
-	arrayList_destroy(writer->localPubs);
-
-	celixThreadMutex_unlock(&writer->localPubsLock);
-	celixThreadMutex_destroy(&(writer->localPubsLock));
-
-	free(writer);
-}
-
-celix_status_t etcdWriter_addPublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP, bool storeEP){
-	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
-	if(storeEP){
-		const char *fwUUID = NULL;
-		bundleContext_getProperty(writer->pubsub_discovery->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
-		if(fwUUID && strcmp(pubEP->frameworkUUID, fwUUID) == 0) {
-			celixThreadMutex_lock(&writer->localPubsLock);
-			pubsub_endpoint_pt p = NULL;
-			pubsubEndpoint_clone(pubEP, &p);
-			arrayList_add(writer->localPubs,p);
-			celixThreadMutex_unlock(&writer->localPubsLock);
-		}
-	}
-
-	char *key;
-
-	const char* ttlStr = NULL;
-	int ttl = 0;
-
-	// determine ttl
-	if ((bundleContext_getProperty(writer->pubsub_discovery->context, CFG_ETCD_TTL, &ttlStr) != CELIX_SUCCESS) || !ttlStr) {
-		ttl = DEFAULT_ETCD_TTL;
-	} else {
-		char* endptr = NULL;
-		errno = 0;
-		ttl = strtol(ttlStr, &endptr, 10);
-		if (*endptr || errno != 0) {
-			ttl = DEFAULT_ETCD_TTL;
-		}
-	}
-
-	const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
-
-	asprintf(&key,"%s/%s/%s/%s/%ld",rootPath,pubEP->scope,pubEP->topic,pubEP->frameworkUUID,pubEP->serviceID);
-
-	if(!etcd_set(key,pubEP->endpoint,ttl,false)){
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-	FREE_MEM(key);
-	return status;
-}
-
-celix_status_t etcdWriter_deletePublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP) {
-	celix_status_t status = CELIX_SUCCESS;
-	char *key = NULL;
-
-	const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
-
-	asprintf(&key, "%s/%s/%s/%s/%ld", rootPath, pubEP->scope, pubEP->topic, pubEP->frameworkUUID, pubEP->serviceID);
-
-	celixThreadMutex_lock(&writer->localPubsLock);
-	for (unsigned int i = 0; i < arrayList_size(writer->localPubs); i++) {
-		pubsub_endpoint_pt ep = arrayList_get(writer->localPubs, i);
-		if (pubsubEndpoint_equals(ep, pubEP)) {
-			arrayList_remove(writer->localPubs, i);
-			pubsubEndpoint_destroy(ep);
-			break;
-		}
-	}
-	celixThreadMutex_unlock(&writer->localPubsLock);
-
-	if (etcd_del(key)) {
-		printf("Failed to remove key %s from ETCD\n",key);
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-	FREE_MEM(key);
-	return status;
-}
-
-static void* etcdWriter_run(void* data) {
-	etcd_writer_pt writer = (etcd_writer_pt)data;
-	while(writer->running) {
-		celixThreadMutex_lock(&writer->localPubsLock);
-		for(int i=0; i < arrayList_size(writer->localPubs); i++) {
-			etcdWriter_addPublisherEndpoint(writer,(pubsub_endpoint_pt)arrayList_get(writer->localPubs,i),false);
-		}
-		celixThreadMutex_unlock(&writer->localPubsLock);
-		sleep(DEFAULT_ETCD_TTL / 2);
-	}
-
-	return NULL;
-}
-
-static const char* etcdWriter_getRootPath(bundle_context_pt context) {
-	const char* rootPath = NULL;
-	bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath);
-	if(rootPath == NULL) {
-		rootPath = DEFAULT_ETCD_ROOTPATH;
-	}
-	return rootPath;
-}
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/psd_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/psd_activator.c b/pubsub/pubsub_discovery/private/src/psd_activator.c
deleted file mode 100644
index 89a517d..0000000
--- a/pubsub/pubsub_discovery/private/src/psd_activator.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "bundle_activator.h"
-#include "service_tracker.h"
-#include "service_registration.h"
-#include "constants.h"
-#include "celix_log.h"
-
-#include "pubsub_common.h"
-#include "publisher_endpoint_announce.h"
-#include "pubsub_discovery.h"
-#include "pubsub_discovery_impl.h"
-
-struct activator {
-	bundle_context_pt context;
-	pubsub_discovery_pt pubsub_discovery;
-
-	service_tracker_pt pstmPublishersTracker;
-
-	publisher_endpoint_announce_pt publisherEPAnnounce;
-	service_registration_pt publisherEPAnnounceService;
-};
-
-static celix_status_t createTMPublisherAnnounceTracker(struct activator *activator, service_tracker_pt *tracker) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(activator->pubsub_discovery,
-			NULL,
-			pubsub_discovery_tmPublisherAnnounceAdded,
-			pubsub_discovery_tmPublisherAnnounceModified,
-			pubsub_discovery_tmPublisherAnnounceRemoved,
-			&customizer);
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_create(activator->context, (char *) PUBSUB_TM_ANNOUNCE_PUBLISHER_SERVICE, customizer, tracker);
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	struct activator* activator = calloc(1, sizeof(*activator));
-
-	if (activator) {
-		activator->context = context;
-		activator->pstmPublishersTracker = NULL;
-		activator->publisherEPAnnounce = NULL;
-		activator->publisherEPAnnounceService = NULL;
-
-		status = pubsub_discovery_create(context, &activator->pubsub_discovery);
-
-		if (status == CELIX_SUCCESS) {
-			status = createTMPublisherAnnounceTracker(activator, &(activator->pstmPublishersTracker));
-		}
-
-		if (status == CELIX_SUCCESS) {
-			*userData = activator;
-		} else {
-			free(activator);
-		}
-	} else {
-		status = CELIX_ENOMEM;
-	}
-
-	return status;
-
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	struct activator *activator = userData;
-
-	publisher_endpoint_announce_pt pubEPAnnouncer = calloc(1, sizeof(*pubEPAnnouncer));
-
-	if (pubEPAnnouncer) {
-
-		pubEPAnnouncer->handle = activator->pubsub_discovery;
-		pubEPAnnouncer->announcePublisher = pubsub_discovery_announcePublisher;
-		pubEPAnnouncer->removePublisher = pubsub_discovery_removePublisher;
-		pubEPAnnouncer->interestedInTopic = pubsub_discovery_interestedInTopic;
-		pubEPAnnouncer->uninterestedInTopic = pubsub_discovery_uninterestedInTopic;
-		activator->publisherEPAnnounce = pubEPAnnouncer;
-
-		properties_pt props = properties_create();
-		properties_set(props, "PUBSUB_DISCOVERY", "true");
-
-		// pubsub_discovery_start needs to be first to initalize the propert etcd_watcher values
-		status = pubsub_discovery_start(activator->pubsub_discovery);
-
-		if (status == CELIX_SUCCESS) {
-			status = serviceTracker_open(activator->pstmPublishersTracker);
-		}
-
-		if (status == CELIX_SUCCESS) {
-			status = bundleContext_registerService(context, (char *) PUBSUB_DISCOVERY_SERVICE, pubEPAnnouncer, props, &activator->publisherEPAnnounceService);
-		}
-
-
-	}
-	else{
-		status = CELIX_ENOMEM;
-	}
-
-	if(status!=CELIX_SUCCESS && pubEPAnnouncer!=NULL){
-		free(pubEPAnnouncer);
-	}
-
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	status += pubsub_discovery_stop(activator->pubsub_discovery);
-
-	status += serviceTracker_close(activator->pstmPublishersTracker);
-
-	status += serviceRegistration_unregister(activator->publisherEPAnnounceService);
-
-	if (status == CELIX_SUCCESS) {
-		free(activator->publisherEPAnnounce);
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	status += serviceTracker_destroy(activator->pstmPublishersTracker);
-	status += pubsub_discovery_destroy(activator->pubsub_discovery);
-
-	activator->publisherEPAnnounce = NULL;
-	activator->publisherEPAnnounceService = NULL;
-	activator->pstmPublishersTracker = NULL;
-	activator->pubsub_discovery = NULL;
-	activator->context = NULL;
-
-	free(activator);
-
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/pubsub_discovery_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/pubsub_discovery_impl.c b/pubsub/pubsub_discovery/private/src/pubsub_discovery_impl.c
deleted file mode 100644
index 94a8e11..0000000
--- a/pubsub/pubsub_discovery/private/src/pubsub_discovery_impl.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <netdb.h>
-#include <netinet/in.h>
-
-#include "constants.h"
-#include "celix_threads.h"
-#include "bundle_context.h"
-#include "array_list.h"
-#include "utils.h"
-#include "celix_errno.h"
-#include "filter.h"
-#include "service_reference.h"
-#include "service_registration.h"
-
-#include "publisher_endpoint_announce.h"
-#include "etcd_common.h"
-#include "etcd_watcher.h"
-#include "etcd_writer.h"
-#include "pubsub_endpoint.h"
-#include "pubsub_discovery_impl.h"
-
-/* Discovery activator functions */
-celix_status_t pubsub_discovery_create(bundle_context_pt context, pubsub_discovery_pt *ps_discovery) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*ps_discovery = calloc(1, sizeof(**ps_discovery));
-
-	if (*ps_discovery == NULL) {
-		status = CELIX_ENOMEM;
-	}
-	else{
-		(*ps_discovery)->context = context;
-		(*ps_discovery)->discoveredPubs = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-		(*ps_discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
-		(*ps_discovery)->watchers = hashMap_create(utils_stringHash,NULL,utils_stringEquals, NULL);
-		celixThreadMutex_create(&(*ps_discovery)->listenerReferencesMutex, NULL);
-		celixThreadMutex_create(&(*ps_discovery)->discoveredPubsMutex, NULL);
-		celixThreadMutex_create(&(*ps_discovery)->watchersMutex, NULL);
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_discovery_destroy(pubsub_discovery_pt ps_discovery) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ps_discovery->discoveredPubsMutex);
-
-	hash_map_iterator_pt iter = hashMapIterator_create(ps_discovery->discoveredPubs);
-
-	while (hashMapIterator_hasNext(iter)) {
-		array_list_pt pubEP_list = (array_list_pt) hashMapIterator_nextValue(iter);
-
-		for(int i=0; i < arrayList_size(pubEP_list); i++) {
-			pubsubEndpoint_destroy(((pubsub_endpoint_pt)arrayList_get(pubEP_list,i)));
-		}
-		arrayList_destroy(pubEP_list);
-	}
-
-	hashMapIterator_destroy(iter);
-
-	hashMap_destroy(ps_discovery->discoveredPubs, true, false);
-	ps_discovery->discoveredPubs = NULL;
-
-	celixThreadMutex_unlock(&ps_discovery->discoveredPubsMutex);
-
-	celixThreadMutex_destroy(&ps_discovery->discoveredPubsMutex);
-
-
-	celixThreadMutex_lock(&ps_discovery->listenerReferencesMutex);
-
-	hashMap_destroy(ps_discovery->listenerReferences, false, false);
-	ps_discovery->listenerReferences = NULL;
-
-	celixThreadMutex_unlock(&ps_discovery->listenerReferencesMutex);
-
-	celixThreadMutex_destroy(&ps_discovery->listenerReferencesMutex);
-
-	free(ps_discovery);
-
-	return status;
-}
-
-celix_status_t pubsub_discovery_start(pubsub_discovery_pt ps_discovery) {
-    celix_status_t status = CELIX_SUCCESS;
-    status = etcdCommon_init(ps_discovery->context);
-    ps_discovery->writer = etcdWriter_create(ps_discovery);
-
-    return status;
-}
-
-celix_status_t pubsub_discovery_stop(pubsub_discovery_pt ps_discovery) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char* fwUUID = NULL;
-
-    bundleContext_getProperty(ps_discovery->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
-    if (fwUUID == NULL) {
-        printf("PSD: Cannot retrieve fwUUID.\n");
-        return CELIX_INVALID_BUNDLE_CONTEXT;
-    }
-
-    celixThreadMutex_lock(&ps_discovery->watchersMutex);
-
-    hash_map_iterator_pt iter = hashMapIterator_create(ps_discovery->watchers);
-    while (hashMapIterator_hasNext(iter)) {
-        struct watcher_info * wi = hashMapIterator_nextValue(iter);
-        etcdWatcher_stop(wi->watcher);
-    }
-    hashMapIterator_destroy(iter);
-
-    celixThreadMutex_lock(&ps_discovery->discoveredPubsMutex);
-
-    /* Unexport all publishers for the local framework, and also delete from ETCD publisher belonging to the local framework */
-
-    iter = hashMapIterator_create(ps_discovery->discoveredPubs);
-    while (hashMapIterator_hasNext(iter)) {
-        array_list_pt pubEP_list = (array_list_pt) hashMapIterator_nextValue(iter);
-
-        int i;
-        for (i = 0; i < arrayList_size(pubEP_list); i++) {
-            pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt) arrayList_get(pubEP_list, i);
-            if (strcmp(pubEP->frameworkUUID, fwUUID) == 0) {
-                etcdWriter_deletePublisherEndpoint(ps_discovery->writer, pubEP);
-            } else {
-                pubsub_discovery_informPublishersListeners(ps_discovery, pubEP, false);
-                arrayList_remove(pubEP_list, i);
-                pubsubEndpoint_destroy(pubEP);
-                i--;
-            }
-        }
-    }
-
-    hashMapIterator_destroy(iter);
-
-    celixThreadMutex_unlock(&ps_discovery->discoveredPubsMutex);
-    etcdWriter_destroy(ps_discovery->writer);
-
-    iter = hashMapIterator_create(ps_discovery->watchers);
-    while (hashMapIterator_hasNext(iter)) {
-        struct watcher_info * wi = hashMapIterator_nextValue(iter);
-        etcdWatcher_destroy(wi->watcher);
-    }
-    hashMapIterator_destroy(iter);
-    hashMap_destroy(ps_discovery->watchers, true, true);
-    celixThreadMutex_unlock(&ps_discovery->watchersMutex);
-    return status;
-}
-
-/* Functions called by the etcd_watcher */
-
-celix_status_t pubsub_discovery_addNode(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP) {
-	celix_status_t status = CELIX_SUCCESS;
-	bool inform=false;
-	celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
-
-	char *pubs_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
-	array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pubs_key);
-	if(pubEP_list==NULL){
-		arrayList_create(&pubEP_list);
-		arrayList_add(pubEP_list,pubEP);
-		hashMap_put(pubsub_discovery->discoveredPubs,strdup(pubs_key),pubEP_list);
-		inform=true;
-	}
-	else{
-		int i;
-		bool found = false;
-		for(i=0;i<arrayList_size(pubEP_list) && !found;i++){
-			found = pubsubEndpoint_equals(pubEP,(pubsub_endpoint_pt)arrayList_get(pubEP_list,i));
-		}
-		if(found){
-			pubsubEndpoint_destroy(pubEP);
-		}
-		else{
-			arrayList_add(pubEP_list,pubEP);
-			inform=true;
-    	}
-	}
-	free(pubs_key);
-
-	celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
-
-	if(inform){
-	    status = pubsub_discovery_informPublishersListeners(pubsub_discovery,pubEP,true);
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_discovery_removeNode(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP) {
-    celix_status_t status = CELIX_SUCCESS;
-    pubsub_endpoint_pt p = NULL;
-    bool found = false;
-
-    celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
-    char *pubs_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
-    array_list_pt pubEP_list = (array_list_pt) hashMap_get(pubsub_discovery->discoveredPubs, pubs_key);
-    free(pubs_key);
-    if (pubEP_list == NULL) {
-        printf("PSD: Cannot find any registered publisher for topic %s. Something is not consistent.\n", pubEP->topic);
-        status = CELIX_ILLEGAL_STATE;
-    } else {
-        int i;
-
-        for (i = 0; !found && i < arrayList_size(pubEP_list); i++) {
-            p = arrayList_get(pubEP_list, i);
-            found = pubsubEndpoint_equals(pubEP, p);
-            if (found) {
-                arrayList_remove(pubEP_list, i);
-                pubsubEndpoint_destroy(p);
-            }
-        }
-    }
-
-    celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
-    if (found) {
-        status = pubsub_discovery_informPublishersListeners(pubsub_discovery, pubEP, false);
-    }
-    pubsubEndpoint_destroy(pubEP);
-
-    return status;
-}
-
-/* Callback to the pubsub_topology_manager */
-celix_status_t pubsub_discovery_informPublishersListeners(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP, bool epAdded) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	// Inform listeners of new publisher endpoint
-	celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
-
-	if (pubsub_discovery->listenerReferences != NULL) {
-		hash_map_iterator_pt iter = hashMapIterator_create(pubsub_discovery->listenerReferences);
-		while (hashMapIterator_hasNext(iter)) {
-			service_reference_pt reference = hashMapIterator_nextKey(iter);
-
-			publisher_endpoint_announce_pt listener = NULL;
-
-			bundleContext_getService(pubsub_discovery->context, reference, (void**) &listener);
-            if (epAdded) {
-                listener->announcePublisher(listener->handle, pubEP);
-            } else {
-                listener->removePublisher(listener->handle, pubEP);
-            }
-            bundleContext_ungetService(pubsub_discovery->context, reference, NULL);
-		}
-		hashMapIterator_destroy(iter);
-	}
-
-	celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
-
-	return status;
-}
-
-
-/* Service's functions implementation */
-celix_status_t pubsub_discovery_announcePublisher(void *handle, pubsub_endpoint_pt pubEP) {
-	celix_status_t status = CELIX_SUCCESS;
-	printf("pubsub_discovery_announcePublisher : %s / %s\n", pubEP->topic, pubEP->endpoint);
-	pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
-
-	celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
-
-	char *pub_key = createScopeTopicKey(pubEP->scope,pubEP->topic);
-	array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pub_key);
-
-	if(pubEP_list==NULL){
-		arrayList_create(&pubEP_list);
-		hashMap_put(pubsub_discovery->discoveredPubs,strdup(pub_key),pubEP_list);
-	}
-	free(pub_key);
-	pubsub_endpoint_pt p = NULL;
-	pubsubEndpoint_clone(pubEP, &p);
-
-	arrayList_add(pubEP_list,p);
-
-	status = etcdWriter_addPublisherEndpoint(pubsub_discovery->writer,p,true);
-
-	celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
-
-	return status;
-}
-
-celix_status_t pubsub_discovery_removePublisher(void *handle, pubsub_endpoint_pt pubEP) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
-
-	celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
-
-	char *pub_key = createScopeTopicKey(pubEP->scope,pubEP->topic);
-	array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pub_key);
-	free(pub_key);
-	if(pubEP_list==NULL){
-		printf("PSD: Cannot find any registered publisher for topic %s. Something is not consistent.\n",pubEP->topic);
-		status = CELIX_ILLEGAL_STATE;
-	}
-	else{
-
-		int i;
-		bool found = false;
-		pubsub_endpoint_pt p = NULL;
-
-		for(i=0;!found && i<arrayList_size(pubEP_list);i++){
-			p = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
-			found = pubsubEndpoint_equals(pubEP,p);
-		}
-
-		if(!found){
-			printf("PSD: Trying to remove a not existing endpoint. Something is not consistent.\n");
-			status = CELIX_ILLEGAL_STATE;
-		}
-		else{
-
-			arrayList_removeElement(pubEP_list,p);
-
-			status = etcdWriter_deletePublisherEndpoint(pubsub_discovery->writer,p);
-
-			pubsubEndpoint_destroy(p);
-		}
-	}
-
-	celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
-
-	return status;
-}
-
-celix_status_t pubsub_discovery_interestedInTopic(void *handle, const char* scope, const char* topic) {
-    pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
-
-    char *scope_topic_key = createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&pubsub_discovery->watchersMutex);
-    struct watcher_info * wi = hashMap_get(pubsub_discovery->watchers, scope_topic_key);
-    if(wi) {
-        wi->nr_references++;
-        free(scope_topic_key);
-    } else {
-        wi = calloc(1, sizeof(*wi));
-        etcdWatcher_create(pubsub_discovery, pubsub_discovery->context, scope, topic, &wi->watcher);
-        wi->nr_references = 1;
-        hashMap_put(pubsub_discovery->watchers, scope_topic_key, wi);
-    }
-
-    celixThreadMutex_unlock(&pubsub_discovery->watchersMutex);
-
-    return CELIX_SUCCESS;
-}
-
-celix_status_t pubsub_discovery_uninterestedInTopic(void *handle, const char* scope, const char* topic) {
-    pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
-
-    char *scope_topic_key = createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&pubsub_discovery->watchersMutex);
-
-    hash_map_entry_pt entry =  hashMap_getEntry(pubsub_discovery->watchers, scope_topic_key);
-    if(entry) {
-        struct watcher_info * wi = hashMapEntry_getValue(entry);
-        wi->nr_references--;
-        if(wi->nr_references == 0) {
-            char *key = hashMapEntry_getKey(entry);
-            hashMap_remove(pubsub_discovery->watchers, scope_topic_key);
-            free(key);
-            free(scope_topic_key);
-            etcdWatcher_stop(wi->watcher);
-            etcdWatcher_destroy(wi->watcher);
-            free(wi);
-        }
-    } else {
-        fprintf(stderr, "[DISC] Inconsistency error: Removing unknown topic %s\n", topic);
-    }
-    celixThreadMutex_unlock(&pubsub_discovery->watchersMutex);
-    return CELIX_SUCCESS;
-}
-
-/* pubsub_topology_manager tracker callbacks */
-
-celix_status_t pubsub_discovery_tmPublisherAnnounceAdded(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt)handle;
-	publisher_endpoint_announce_pt listener = (publisher_endpoint_announce_pt)service;
-
-	celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
-	celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
-
-	/* Notify the PSTM about discovered publisher endpoints */
-	hash_map_iterator_pt iter = hashMapIterator_create(pubsub_discovery->discoveredPubs);
-	while(hashMapIterator_hasNext(iter)){
-		array_list_pt pubEP_list = (array_list_pt)hashMapIterator_nextValue(iter);
-		int i;
-		for(i=0;i<arrayList_size(pubEP_list);i++){
-			pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
-			status += listener->announcePublisher(listener->handle, pubEP);
-		}
-	}
-
-	hashMapIterator_destroy(iter);
-
-	hashMap_put(pubsub_discovery->listenerReferences, reference, NULL);
-
-	celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
-	celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
-
-	printf("PSD: pubsub_tm_announce_publisher added.\n");
-
-	return status;
-}
-
-celix_status_t pubsub_discovery_tmPublisherAnnounceModified(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	status = pubsub_discovery_tmPublisherAnnounceRemoved(handle, reference, service);
-	if (status == CELIX_SUCCESS) {
-		status = pubsub_discovery_tmPublisherAnnounceAdded(handle, reference, service);
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_discovery_tmPublisherAnnounceRemoved(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-	pubsub_discovery_pt pubsub_discovery = handle;
-
-	celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
-
-	if (pubsub_discovery->listenerReferences != NULL) {
-		if (hashMap_remove(pubsub_discovery->listenerReferences, reference)) {
-			printf("PSD: pubsub_tm_announce_publisher removed.\n");
-		}
-	}
-	celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
-
-	return status;
-}
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/public/include/pubsub_discovery.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/public/include/pubsub_discovery.h b/pubsub/pubsub_discovery/public/include/pubsub_discovery.h
deleted file mode 100644
index f77905a..0000000
--- a/pubsub/pubsub_discovery/public/include/pubsub_discovery.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef PUBSUB_DISCOVERY_H_
-#define PUBSUB_DISCOVERY_H_
-
-typedef struct pubsub_discovery *pubsub_discovery_pt;
-
-
-#endif /* PUBSUB_DISCOVERY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_common.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_common.c b/pubsub/pubsub_discovery/src/etcd_common.c
new file mode 100644
index 0000000..c757801
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_common.c
@@ -0,0 +1,82 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "celix_log.h"
+#include "constants.h"
+
+#include <curl/curl.h>
+#include "etcd.h"
+#include "etcd_watcher.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_discovery_impl.h"
+
+
+#define MAX_ROOTNODE_LENGTH		128
+#define MAX_LOCALNODE_LENGTH 	4096
+#define MAX_FIELD_LENGTH		128
+
+#define CFG_ETCD_SERVER_IP		"PUBSUB_DISCOVERY_ETCD_SERVER_IP"
+#define DEFAULT_ETCD_SERVER_IP	"127.0.0.1"
+
+#define CFG_ETCD_SERVER_PORT	"PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
+#define DEFAULT_ETCD_SERVER_PORT 2379
+
+// be careful - this should be higher than the curl timeout
+#define CFG_ETCD_TTL   "DISCOVERY_ETCD_TTL"
+#define DEFAULT_ETCD_TTL 30
+
+
+celix_status_t etcdCommon_init(bundle_context_pt context) {
+    celix_status_t status = CELIX_SUCCESS;
+    const char* etcd_server = NULL;
+    const char* etcd_port_string = NULL;
+    int etcd_port = 0;
+
+    if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_IP, &etcd_server) != CELIX_SUCCESS) || !etcd_server) {
+        etcd_server = DEFAULT_ETCD_SERVER_IP;
+    }
+
+    if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_PORT, &etcd_port_string) != CELIX_SUCCESS) || !etcd_port_string) {
+        etcd_port = DEFAULT_ETCD_SERVER_PORT;
+    } else {
+        char* endptr = NULL;
+        errno = 0;
+        etcd_port = strtol(etcd_port_string, &endptr, 10);
+        if (*endptr || errno != 0) {
+            etcd_port = DEFAULT_ETCD_SERVER_PORT;
+        }
+    }
+
+    printf("PSD: Using discovery HOST:PORT: %s:%i\n", etcd_server, etcd_port);
+
+    if (etcd_init(etcd_server, etcd_port, CURL_GLOBAL_DEFAULT) != 0) {
+        status = CELIX_BUNDLE_EXCEPTION;
+    } else {
+        status = CELIX_SUCCESS;
+    }
+
+    return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_common.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_common.h b/pubsub/pubsub_discovery/src/etcd_common.h
new file mode 100644
index 0000000..7a3e7b6
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_common.h
@@ -0,0 +1,28 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef ETCD_COMMON_H_
+#define ETCD_COMMON_H_
+
+#include "bundle_context.h"
+#include "celix_errno.h"
+
+celix_status_t etcdCommon_init(bundle_context_pt context);
+
+#endif /* ETCD_COMMON_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_watcher.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_watcher.c b/pubsub/pubsub_discovery/src/etcd_watcher.c
new file mode 100644
index 0000000..3c3a5a8
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_watcher.c
@@ -0,0 +1,290 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "celix_log.h"
+#include "constants.h"
+
+#include "etcd.h"
+#include "etcd_watcher.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_discovery_impl.h"
+
+
+
+#define MAX_ROOTNODE_LENGTH             128
+#define MAX_LOCALNODE_LENGTH            4096
+#define MAX_FIELD_LENGTH                128
+
+#define CFG_ETCD_ROOT_PATH              "PUBSUB_DISCOVERY_ETCD_ROOT_PATH"
+#define DEFAULT_ETCD_ROOTPATH           "pubsub/discovery"
+
+#define CFG_ETCD_SERVER_IP              "PUBSUB_DISCOVERY_ETCD_SERVER_IP"
+#define DEFAULT_ETCD_SERVER_IP          "127.0.0.1"
+
+#define CFG_ETCD_SERVER_PORT            "PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
+#define DEFAULT_ETCD_SERVER_PORT        2379
+
+// be careful - this should be higher than the curl timeout
+#define CFG_ETCD_TTL                    "DISCOVERY_ETCD_TTL"
+#define DEFAULT_ETCD_TTL                30
+
+
+struct etcd_watcher {
+	pubsub_discovery_pt pubsub_discovery;
+
+	celix_thread_mutex_t watcherLock;
+	celix_thread_t watcherThread;
+
+	char *scope;
+	char *topic;
+	volatile bool running;
+};
+
+struct etcd_writer {
+	pubsub_discovery_pt pubsub_discovery;
+	celix_thread_mutex_t localPubsLock;
+	array_list_pt localPubs;
+	volatile bool running;
+	celix_thread_t writerThread;
+};
+
+
+// note that the rootNode shouldn't have a leading slash
+static celix_status_t etcdWatcher_getTopicRootPath(bundle_context_pt context, const char *scope, const char *topic, char* rootNode, int rootNodeLen) {
+	celix_status_t status = CELIX_SUCCESS;
+	const char* rootPath = NULL;
+
+	if (((bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath)) != CELIX_SUCCESS) || (!rootPath)) {
+		snprintf(rootNode, rootNodeLen, "%s/%s/%s", DEFAULT_ETCD_ROOTPATH, scope, topic);
+	} else {
+		snprintf(rootNode, rootNodeLen, "%s/%s/%s", rootPath, scope, topic);
+	}
+
+	return status;
+}
+
+static celix_status_t etcdWatcher_getRootPath(bundle_context_pt context, char* rootNode) {
+	celix_status_t status = CELIX_SUCCESS;
+	const char* rootPath = NULL;
+
+	if (((bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath)) != CELIX_SUCCESS) || (!rootPath)) {
+		strncpy(rootNode, DEFAULT_ETCD_ROOTPATH, MAX_ROOTNODE_LENGTH);
+	} else {
+		strncpy(rootNode, rootPath, MAX_ROOTNODE_LENGTH);
+	}
+
+	return status;
+}
+
+
+static void add_node(const char *key, const char *value, void* arg) {
+	pubsub_discovery_pt ps_discovery = (pubsub_discovery_pt) arg;
+	pubsub_endpoint_pt pubEP = NULL;
+	celix_status_t status = etcdWatcher_getPublisherEndpointFromKey(ps_discovery, key, value, &pubEP);
+	if(!status && pubEP) {
+		pubsub_discovery_addNode(ps_discovery, pubEP);
+	}
+}
+
+static celix_status_t etcdWatcher_addAlreadyExistingPublishers(pubsub_discovery_pt ps_discovery, const char *rootPath, long long * highestModified) {
+	celix_status_t status = CELIX_SUCCESS;
+	if(etcd_get_directory(rootPath, add_node, ps_discovery, highestModified)) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+	return status;
+}
+
+// gets everything from provided key
+celix_status_t etcdWatcher_getPublisherEndpointFromKey(pubsub_discovery_pt pubsub_discovery, const char* etcdKey, const char* etcdValue, pubsub_endpoint_pt* pubEP) {
+
+	celix_status_t status = CELIX_SUCCESS;
+
+	char rootPath[MAX_ROOTNODE_LENGTH];
+	char *expr = NULL;
+	char scope[MAX_FIELD_LENGTH];
+	char topic[MAX_FIELD_LENGTH];
+	char fwUUID[MAX_FIELD_LENGTH];
+	char serviceId[MAX_FIELD_LENGTH];
+
+	memset(rootPath,0,MAX_ROOTNODE_LENGTH);
+	memset(topic,0,MAX_FIELD_LENGTH);
+	memset(fwUUID,0,MAX_FIELD_LENGTH);
+	memset(serviceId,0,MAX_FIELD_LENGTH);
+
+	etcdWatcher_getRootPath(pubsub_discovery->context, rootPath);
+
+	asprintf(&expr, "/%s/%%[^/]/%%[^/]/%%[^/]/%%[^/].*", rootPath);
+	if(expr) {
+		int foundItems = sscanf(etcdKey, expr, scope, topic, fwUUID, serviceId);
+		free(expr);
+		if (foundItems != 4) { // Could happen when a directory is removed, just don't process this.
+			status = CELIX_ILLEGAL_STATE;
+		}
+		else{
+			status = pubsubEndpoint_create(fwUUID,scope,topic,strtol(serviceId,NULL,10),etcdValue,NULL,pubEP);
+		}
+	}
+	return status;
+}
+
+/*
+ * performs (blocking) etcd_watch calls to check for
+ * changing discovery endpoint information within etcd.
+ */
+static void* etcdWatcher_run(void* data) {
+	etcd_watcher_pt watcher = (etcd_watcher_pt) data;
+	time_t timeBeforeWatch = time(NULL);
+	char rootPath[MAX_ROOTNODE_LENGTH];
+	long long highestModified = 0;
+
+	pubsub_discovery_pt ps_discovery = watcher->pubsub_discovery;
+	bundle_context_pt context = ps_discovery->context;
+
+	memset(rootPath, 0, MAX_ROOTNODE_LENGTH);
+
+	//TODO: add topic to etcd key
+	etcdWatcher_getTopicRootPath(context, watcher->scope, watcher->topic, rootPath, MAX_ROOTNODE_LENGTH);
+	etcdWatcher_addAlreadyExistingPublishers(ps_discovery, rootPath, &highestModified);
+
+	while ((celixThreadMutex_lock(&watcher->watcherLock) == CELIX_SUCCESS) && watcher->running) {
+
+		char *rkey = NULL;
+		char *value = NULL;
+		char *preValue = NULL;
+		char *action = NULL;
+		long long modIndex;
+
+		celixThreadMutex_unlock(&watcher->watcherLock);
+
+		if (etcd_watch(rootPath, highestModified + 1, &action, &preValue, &value, &rkey, &modIndex) == 0 && action != NULL) {
+			pubsub_endpoint_pt pubEP = NULL;
+			if ((strcmp(action, "set") == 0) || (strcmp(action, "create") == 0)) {
+				if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, value, &pubEP) == CELIX_SUCCESS) {
+					pubsub_discovery_addNode(ps_discovery, pubEP);
+				}
+			} else if (strcmp(action, "delete") == 0) {
+				if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, preValue, &pubEP) == CELIX_SUCCESS) {
+					pubsub_discovery_removeNode(ps_discovery, pubEP);
+				}
+			} else if (strcmp(action, "expire") == 0) {
+				if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, preValue, &pubEP) == CELIX_SUCCESS) {
+					pubsub_discovery_removeNode(ps_discovery, pubEP);
+				}
+			} else if (strcmp(action, "update") == 0) {
+				if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, value, &pubEP) == CELIX_SUCCESS) {
+					pubsub_discovery_addNode(ps_discovery, pubEP);
+				}
+			} else {
+				fw_log(logger, OSGI_FRAMEWORK_LOG_INFO, "Unexpected action: %s", action);
+			}
+			highestModified = modIndex;
+		} else if (time(NULL) - timeBeforeWatch <= (DEFAULT_ETCD_TTL / 4)) {
+			sleep(DEFAULT_ETCD_TTL / 4);
+		}
+
+		FREE_MEM(action);
+		FREE_MEM(value);
+		FREE_MEM(preValue);
+		FREE_MEM(rkey);
+
+		/* prevent busy waiting, in case etcd_watch returns false */
+
+
+		if (time(NULL) - timeBeforeWatch > (DEFAULT_ETCD_TTL / 4)) {
+			timeBeforeWatch = time(NULL);
+		}
+
+	}
+
+	if (watcher->running == false) {
+		celixThreadMutex_unlock(&watcher->watcherLock);
+	}
+
+	return NULL;
+}
+
+celix_status_t etcdWatcher_create(pubsub_discovery_pt pubsub_discovery, bundle_context_pt context, const char *scope, const char *topic, etcd_watcher_pt *watcher) {
+	celix_status_t status = CELIX_SUCCESS;
+
+
+	if (pubsub_discovery == NULL) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	(*watcher) = calloc(1, sizeof(struct etcd_watcher));
+
+	if(*watcher == NULL){
+		return CELIX_ENOMEM;
+	}
+
+	(*watcher)->pubsub_discovery = pubsub_discovery;
+	(*watcher)->scope = strdup(scope);
+	(*watcher)->topic = strdup(topic);
+
+
+	celixThreadMutex_create(&(*watcher)->watcherLock, NULL);
+
+	celixThreadMutex_lock(&(*watcher)->watcherLock);
+
+	status = celixThread_create(&(*watcher)->watcherThread, NULL, etcdWatcher_run, *watcher);
+	if (status == CELIX_SUCCESS) {
+		(*watcher)->running = true;
+	}
+
+	celixThreadMutex_unlock(&(*watcher)->watcherLock);
+
+
+	return status;
+}
+
+celix_status_t etcdWatcher_destroy(etcd_watcher_pt watcher) {
+
+	celix_status_t status = CELIX_SUCCESS;
+
+	char rootPath[MAX_ROOTNODE_LENGTH];
+	etcdWatcher_getTopicRootPath(watcher->pubsub_discovery->context, watcher->scope, watcher->topic, rootPath, MAX_ROOTNODE_LENGTH);
+	celixThreadMutex_destroy(&(watcher->watcherLock));
+
+	free(watcher->scope);
+	free(watcher->topic);
+	free(watcher);
+
+	return status;
+}
+
+celix_status_t etcdWatcher_stop(etcd_watcher_pt watcher){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&(watcher->watcherLock));
+	watcher->running = false;
+	celixThreadMutex_unlock(&(watcher->watcherLock));
+
+	celixThread_join(watcher->watcherThread, NULL);
+
+	return status;
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_watcher.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_watcher.h b/pubsub/pubsub_discovery/src/etcd_watcher.h
new file mode 100644
index 0000000..c425e60
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_watcher.h
@@ -0,0 +1,38 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef ETCD_WATCHER_H_
+#define ETCD_WATCHER_H_
+
+#include "bundle_context.h"
+#include "celix_errno.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_endpoint.h"
+
+typedef struct etcd_watcher *etcd_watcher_pt;
+
+celix_status_t etcdWatcher_create(pubsub_discovery_pt discovery,  bundle_context_pt context, const char *scope, const char* topic, etcd_watcher_pt *watcher);
+celix_status_t etcdWatcher_destroy(etcd_watcher_pt watcher);
+celix_status_t etcdWatcher_stop(etcd_watcher_pt watcher);
+
+celix_status_t etcdWatcher_getPublisherEndpointFromKey(pubsub_discovery_pt discovery, const char* key, const char* value, pubsub_endpoint_pt* pubEP);
+
+
+#endif /* ETCD_WATCHER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_writer.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_writer.c b/pubsub/pubsub_discovery/src/etcd_writer.c
new file mode 100644
index 0000000..1c423f3
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_writer.c
@@ -0,0 +1,189 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "celix_log.h"
+#include "constants.h"
+
+#include "etcd.h"
+#include "etcd_writer.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_discovery_impl.h"
+
+#define MAX_ROOTNODE_LENGTH		128
+
+#define CFG_ETCD_ROOT_PATH		"PUBSUB_DISCOVERY_ETCD_ROOT_PATH"
+#define DEFAULT_ETCD_ROOTPATH	"pubsub/discovery"
+
+#define CFG_ETCD_SERVER_IP		"PUBSUB_DISCOVERY_ETCD_SERVER_IP"
+#define DEFAULT_ETCD_SERVER_IP	"127.0.0.1"
+
+#define CFG_ETCD_SERVER_PORT	"PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
+#define DEFAULT_ETCD_SERVER_PORT 2379
+
+// be careful - this should be higher than the curl timeout
+#define CFG_ETCD_TTL   "DISCOVERY_ETCD_TTL"
+#define DEFAULT_ETCD_TTL 30
+
+struct etcd_writer {
+	pubsub_discovery_pt pubsub_discovery;
+	celix_thread_mutex_t localPubsLock;
+	array_list_pt localPubs;
+	volatile bool running;
+	celix_thread_t writerThread;
+};
+
+
+static const char* etcdWriter_getRootPath(bundle_context_pt context);
+static void* etcdWriter_run(void* data);
+
+
+etcd_writer_pt etcdWriter_create(pubsub_discovery_pt disc) {
+	etcd_writer_pt writer = calloc(1, sizeof(*writer));
+	if(writer) {
+		celixThreadMutex_create(&writer->localPubsLock, NULL);
+		arrayList_create(&writer->localPubs);
+		writer->pubsub_discovery = disc;
+		writer->running = true;
+		celixThread_create(&writer->writerThread, NULL, etcdWriter_run, writer);
+	}
+	return writer;
+}
+
+void etcdWriter_destroy(etcd_writer_pt writer) {
+	char dir[MAX_ROOTNODE_LENGTH];
+	const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
+
+	writer->running = false;
+	celixThread_join(writer->writerThread, NULL);
+
+	celixThreadMutex_lock(&writer->localPubsLock);
+	for(int i = 0; i < arrayList_size(writer->localPubs); i++) {
+		pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(writer->localPubs,i);
+		memset(dir,0,MAX_ROOTNODE_LENGTH);
+		snprintf(dir,MAX_ROOTNODE_LENGTH,"%s/%s/%s/%s",rootPath,pubEP->scope,pubEP->topic,pubEP->frameworkUUID);
+		etcd_del(dir);
+		pubsubEndpoint_destroy(pubEP);
+	}
+	arrayList_destroy(writer->localPubs);
+
+	celixThreadMutex_unlock(&writer->localPubsLock);
+	celixThreadMutex_destroy(&(writer->localPubsLock));
+
+	free(writer);
+}
+
+celix_status_t etcdWriter_addPublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP, bool storeEP){
+	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+	if(storeEP){
+		const char *fwUUID = NULL;
+		bundleContext_getProperty(writer->pubsub_discovery->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
+		if(fwUUID && strcmp(pubEP->frameworkUUID, fwUUID) == 0) {
+			celixThreadMutex_lock(&writer->localPubsLock);
+			pubsub_endpoint_pt p = NULL;
+			pubsubEndpoint_clone(pubEP, &p);
+			arrayList_add(writer->localPubs,p);
+			celixThreadMutex_unlock(&writer->localPubsLock);
+		}
+	}
+
+	char *key;
+
+	const char* ttlStr = NULL;
+	int ttl = 0;
+
+	// determine ttl
+	if ((bundleContext_getProperty(writer->pubsub_discovery->context, CFG_ETCD_TTL, &ttlStr) != CELIX_SUCCESS) || !ttlStr) {
+		ttl = DEFAULT_ETCD_TTL;
+	} else {
+		char* endptr = NULL;
+		errno = 0;
+		ttl = strtol(ttlStr, &endptr, 10);
+		if (*endptr || errno != 0) {
+			ttl = DEFAULT_ETCD_TTL;
+		}
+	}
+
+	const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
+
+	asprintf(&key,"%s/%s/%s/%s/%ld",rootPath,pubEP->scope,pubEP->topic,pubEP->frameworkUUID,pubEP->serviceID);
+
+	if(!etcd_set(key,pubEP->endpoint,ttl,false)){
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+	FREE_MEM(key);
+	return status;
+}
+
+celix_status_t etcdWriter_deletePublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP) {
+	celix_status_t status = CELIX_SUCCESS;
+	char *key = NULL;
+
+	const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
+
+	asprintf(&key, "%s/%s/%s/%s/%ld", rootPath, pubEP->scope, pubEP->topic, pubEP->frameworkUUID, pubEP->serviceID);
+
+	celixThreadMutex_lock(&writer->localPubsLock);
+	for (unsigned int i = 0; i < arrayList_size(writer->localPubs); i++) {
+		pubsub_endpoint_pt ep = arrayList_get(writer->localPubs, i);
+		if (pubsubEndpoint_equals(ep, pubEP)) {
+			arrayList_remove(writer->localPubs, i);
+			pubsubEndpoint_destroy(ep);
+			break;
+		}
+	}
+	celixThreadMutex_unlock(&writer->localPubsLock);
+
+	if (etcd_del(key)) {
+		printf("Failed to remove key %s from ETCD\n",key);
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+	FREE_MEM(key);
+	return status;
+}
+
+static void* etcdWriter_run(void* data) {
+	etcd_writer_pt writer = (etcd_writer_pt)data;
+	while(writer->running) {
+		celixThreadMutex_lock(&writer->localPubsLock);
+		for(int i=0; i < arrayList_size(writer->localPubs); i++) {
+			etcdWriter_addPublisherEndpoint(writer,(pubsub_endpoint_pt)arrayList_get(writer->localPubs,i),false);
+		}
+		celixThreadMutex_unlock(&writer->localPubsLock);
+		sleep(DEFAULT_ETCD_TTL / 2);
+	}
+
+	return NULL;
+}
+
+static const char* etcdWriter_getRootPath(bundle_context_pt context) {
+	const char* rootPath = NULL;
+	bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath);
+	if(rootPath == NULL) {
+		rootPath = DEFAULT_ETCD_ROOTPATH;
+	}
+	return rootPath;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_writer.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_writer.h b/pubsub/pubsub_discovery/src/etcd_writer.h
new file mode 100644
index 0000000..3ff98b9
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_writer.h
@@ -0,0 +1,39 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef ETCD_WRITER_H_
+#define ETCD_WRITER_H_
+
+#include "bundle_context.h"
+#include "celix_errno.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_endpoint.h"
+
+typedef struct etcd_writer *etcd_writer_pt;
+
+
+etcd_writer_pt etcdWriter_create(pubsub_discovery_pt discovery);
+void etcdWriter_destroy(etcd_writer_pt writer);
+
+celix_status_t etcdWriter_addPublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP,bool storeEP);
+celix_status_t etcdWriter_deletePublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP);
+
+
+#endif /* ETCD_WRITER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/psd_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/psd_activator.c b/pubsub/pubsub_discovery/src/psd_activator.c
new file mode 100644
index 0000000..89a517d
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/psd_activator.c
@@ -0,0 +1,171 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bundle_activator.h"
+#include "service_tracker.h"
+#include "service_registration.h"
+#include "constants.h"
+#include "celix_log.h"
+
+#include "pubsub_common.h"
+#include "publisher_endpoint_announce.h"
+#include "pubsub_discovery.h"
+#include "pubsub_discovery_impl.h"
+
+struct activator {
+	bundle_context_pt context;
+	pubsub_discovery_pt pubsub_discovery;
+
+	service_tracker_pt pstmPublishersTracker;
+
+	publisher_endpoint_announce_pt publisherEPAnnounce;
+	service_registration_pt publisherEPAnnounceService;
+};
+
+static celix_status_t createTMPublisherAnnounceTracker(struct activator *activator, service_tracker_pt *tracker) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(activator->pubsub_discovery,
+			NULL,
+			pubsub_discovery_tmPublisherAnnounceAdded,
+			pubsub_discovery_tmPublisherAnnounceModified,
+			pubsub_discovery_tmPublisherAnnounceRemoved,
+			&customizer);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(activator->context, (char *) PUBSUB_TM_ANNOUNCE_PUBLISHER_SERVICE, customizer, tracker);
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	struct activator* activator = calloc(1, sizeof(*activator));
+
+	if (activator) {
+		activator->context = context;
+		activator->pstmPublishersTracker = NULL;
+		activator->publisherEPAnnounce = NULL;
+		activator->publisherEPAnnounceService = NULL;
+
+		status = pubsub_discovery_create(context, &activator->pubsub_discovery);
+
+		if (status == CELIX_SUCCESS) {
+			status = createTMPublisherAnnounceTracker(activator, &(activator->pstmPublishersTracker));
+		}
+
+		if (status == CELIX_SUCCESS) {
+			*userData = activator;
+		} else {
+			free(activator);
+		}
+	} else {
+		status = CELIX_ENOMEM;
+	}
+
+	return status;
+
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	struct activator *activator = userData;
+
+	publisher_endpoint_announce_pt pubEPAnnouncer = calloc(1, sizeof(*pubEPAnnouncer));
+
+	if (pubEPAnnouncer) {
+
+		pubEPAnnouncer->handle = activator->pubsub_discovery;
+		pubEPAnnouncer->announcePublisher = pubsub_discovery_announcePublisher;
+		pubEPAnnouncer->removePublisher = pubsub_discovery_removePublisher;
+		pubEPAnnouncer->interestedInTopic = pubsub_discovery_interestedInTopic;
+		pubEPAnnouncer->uninterestedInTopic = pubsub_discovery_uninterestedInTopic;
+		activator->publisherEPAnnounce = pubEPAnnouncer;
+
+		properties_pt props = properties_create();
+		properties_set(props, "PUBSUB_DISCOVERY", "true");
+
+		// pubsub_discovery_start needs to be first to initalize the propert etcd_watcher values
+		status = pubsub_discovery_start(activator->pubsub_discovery);
+
+		if (status == CELIX_SUCCESS) {
+			status = serviceTracker_open(activator->pstmPublishersTracker);
+		}
+
+		if (status == CELIX_SUCCESS) {
+			status = bundleContext_registerService(context, (char *) PUBSUB_DISCOVERY_SERVICE, pubEPAnnouncer, props, &activator->publisherEPAnnounceService);
+		}
+
+
+	}
+	else{
+		status = CELIX_ENOMEM;
+	}
+
+	if(status!=CELIX_SUCCESS && pubEPAnnouncer!=NULL){
+		free(pubEPAnnouncer);
+	}
+
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	status += pubsub_discovery_stop(activator->pubsub_discovery);
+
+	status += serviceTracker_close(activator->pstmPublishersTracker);
+
+	status += serviceRegistration_unregister(activator->publisherEPAnnounceService);
+
+	if (status == CELIX_SUCCESS) {
+		free(activator->publisherEPAnnounce);
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	status += serviceTracker_destroy(activator->pstmPublishersTracker);
+	status += pubsub_discovery_destroy(activator->pubsub_discovery);
+
+	activator->publisherEPAnnounce = NULL;
+	activator->publisherEPAnnounceService = NULL;
+	activator->pstmPublishersTracker = NULL;
+	activator->pubsub_discovery = NULL;
+	activator->context = NULL;
+
+	free(activator);
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/pubsub_discovery.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/pubsub_discovery.h b/pubsub/pubsub_discovery/src/pubsub_discovery.h
new file mode 100644
index 0000000..f77905a
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/pubsub_discovery.h
@@ -0,0 +1,26 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef PUBSUB_DISCOVERY_H_
+#define PUBSUB_DISCOVERY_H_
+
+typedef struct pubsub_discovery *pubsub_discovery_pt;
+
+
+#endif /* PUBSUB_DISCOVERY_H_ */


[03/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/topology_manager.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/topology_manager.c b/remote_services/topology_manager/src/topology_manager.c
new file mode 100644
index 0000000..6472b01
--- /dev/null
+++ b/remote_services/topology_manager/src/topology_manager.c
@@ -0,0 +1,985 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * topology_manager.c
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "celixbool.h"
+#include "topology_manager.h"
+#include "bundle_context.h"
+#include "constants.h"
+#include "bundle.h"
+#include "remote_service_admin.h"
+#include "remote_constants.h"
+#include "filter.h"
+#include "listener_hook_service.h"
+#include "utils.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "log_service.h"
+#include "log_helper.h"
+#include "topology_manager.h"
+#include "scope.h"
+#include "hash_map.h"
+
+struct topology_manager {
+	bundle_context_pt context;
+
+	celix_thread_mutex_t rsaListLock;
+	celix_thread_mutexattr_t rsaListLockAttr;
+	array_list_pt rsaList;
+
+	celix_thread_mutex_t listenerListLock;
+	hash_map_pt listenerList;
+
+	celix_thread_mutex_t exportedServicesLock;
+	hash_map_pt exportedServices;
+
+	celix_thread_mutex_t importedServicesLock;
+	celix_thread_mutexattr_t importedServicesLockAttr;
+	hash_map_pt importedServices;
+
+	scope_pt scope;
+
+	log_helper_pt loghelper;
+};
+
+celix_status_t topologyManager_exportScopeChanged(void *handle, char *service_name);
+celix_status_t topologyManager_importScopeChanged(void *handle, char *service_name);
+celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations);
+celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export);
+
+celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager, void **scope) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*manager = calloc(1, sizeof(**manager));
+
+	if (!*manager) {
+		return CELIX_ENOMEM;
+	}
+
+	(*manager)->context = context;
+	(*manager)->rsaList = NULL;
+
+	arrayList_create(&(*manager)->rsaList);
+
+
+	celixThreadMutexAttr_create(&(*manager)->rsaListLockAttr);
+	celixThreadMutexAttr_settype(&(*manager)->rsaListLockAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+	celixThreadMutex_create(&(*manager)->rsaListLock, &(*manager)->rsaListLockAttr);
+
+	celixThreadMutexAttr_create(&(*manager)->importedServicesLockAttr);
+	celixThreadMutexAttr_settype(&(*manager)->importedServicesLockAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+	celixThreadMutex_create(&(*manager)->importedServicesLock, &(*manager)->importedServicesLockAttr);
+
+	celixThreadMutex_create(&(*manager)->exportedServicesLock, NULL);
+	celixThreadMutex_create(&(*manager)->listenerListLock, NULL);
+
+	(*manager)->listenerList = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+	(*manager)->exportedServices = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+	(*manager)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
+
+	status = scope_scopeCreate(*manager, &(*manager)->scope);
+	scope_setExportScopeChangedCallback((*manager)->scope, topologyManager_exportScopeChanged);
+	scope_setImportScopeChangedCallback((*manager)->scope, topologyManager_importScopeChanged);
+	*scope = (*manager)->scope;
+
+	(*manager)->loghelper = logHelper;
+
+
+	return status;
+}
+
+celix_status_t topologyManager_destroy(topology_manager_pt manager) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&manager->listenerListLock);
+	hashMap_destroy(manager->listenerList, false, false);
+
+	celixThreadMutex_unlock(&manager->listenerListLock);
+	celixThreadMutex_destroy(&manager->listenerListLock);
+
+	celixThreadMutex_lock(&manager->rsaListLock);
+
+	arrayList_destroy(manager->rsaList);
+
+	celixThreadMutex_unlock(&manager->rsaListLock);
+	celixThreadMutex_destroy(&manager->rsaListLock);
+	celixThreadMutexAttr_destroy(&manager->rsaListLockAttr);
+
+	celixThreadMutex_lock(&manager->exportedServicesLock);
+
+	hashMap_destroy(manager->exportedServices, false, false);
+
+	celixThreadMutex_unlock(&manager->exportedServicesLock);
+	celixThreadMutex_destroy(&manager->exportedServicesLock);
+
+	celixThreadMutex_lock(&manager->importedServicesLock);
+
+	hashMap_destroy(manager->importedServices, false, false);
+
+	celixThreadMutex_unlock(&manager->importedServicesLock);
+	celixThreadMutex_destroy(&manager->importedServicesLock);
+	celixThreadMutexAttr_destroy(&manager->importedServicesLockAttr);
+
+	scope_scopeDestroy(manager->scope);
+	free(manager);
+
+	return status;
+}
+
+celix_status_t topologyManager_closeImports(topology_manager_pt manager) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&manager->importedServicesLock);
+
+	hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
+	while (hashMapIterator_hasNext(iter)) {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		endpoint_description_pt ep = hashMapEntry_getKey(entry);
+		hash_map_pt imports = hashMapEntry_getValue(entry);
+
+		if (imports != NULL) {
+			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", ep->service, ep->id);
+			hash_map_iterator_pt importsIter = hashMapIterator_create(imports);
+
+			while (hashMapIterator_hasNext(importsIter)) {
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter);
+
+				remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
+				import_registration_pt import = hashMapEntry_getValue(entry);
+
+				status = rsa->importRegistration_close(rsa->admin, import);
+				if (status == CELIX_SUCCESS) {
+					hashMapIterator_remove(importsIter);
+				}
+			}
+			hashMapIterator_destroy(importsIter);
+
+			hashMapIterator_remove(iter);
+
+			hashMap_destroy(imports, false, false);
+		}
+	}
+	hashMapIterator_destroy(iter);
+
+	status = celixThreadMutex_unlock(&manager->importedServicesLock);
+
+	return status;
+}
+
+celix_status_t topologyManager_rsaAdding(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status;
+	topology_manager_pt manager = (topology_manager_pt) handle;
+
+	status = bundleContext_getService(manager->context, reference, service);
+
+	return status;
+}
+
+celix_status_t topologyManager_rsaAdded(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status;
+	topology_manager_pt manager = (topology_manager_pt) handle;
+	properties_pt serviceProperties = NULL;
+	remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service;
+	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added RSA");
+
+	status = celixThreadMutex_lock(&manager->rsaListLock);
+
+	if (status == CELIX_SUCCESS) {
+		arrayList_add(manager->rsaList, rsa);
+		status = celixThreadMutex_unlock(&manager->rsaListLock);
+	}
+
+	// add already imported services to new rsa
+	if (status == CELIX_SUCCESS) {
+		status = celixThreadMutex_lock(&manager->importedServicesLock);
+
+		if (status == CELIX_SUCCESS) {
+			hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices);
+
+			while (hashMapIterator_hasNext(importedServicesIterator)) {
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator);
+				endpoint_description_pt endpoint = hashMapEntry_getKey(entry);
+				if (scope_allowImport(manager->scope, endpoint)) {
+					import_registration_pt import = NULL;
+					status = rsa->importService(rsa->admin, endpoint, &import);
+
+					if (status == CELIX_SUCCESS) {
+						hash_map_pt imports = hashMapEntry_getValue(entry);
+
+						if (imports == NULL) {
+							imports = hashMap_create(NULL, NULL, NULL, NULL);
+							hashMap_put(manager->importedServices,endpoint,imports);
+						}
+
+						hashMap_put(imports, service, import);
+					}
+				}
+			}
+
+			hashMapIterator_destroy(importedServicesIterator);
+
+			celixThreadMutex_unlock(&manager->importedServicesLock);
+		}
+	}
+
+	// add already exported services to new rsa
+	if (status == CELIX_SUCCESS) {
+		status = celixThreadMutex_lock(&manager->exportedServicesLock);
+
+		if (status == CELIX_SUCCESS) {
+			hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices);
+
+			while (hashMapIterator_hasNext(exportedServicesIterator)) {
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator);
+				service_reference_pt reference = hashMapEntry_getKey(entry);
+				const char* serviceId = NULL;
+
+				serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+
+				scope_getExportProperties(manager->scope, reference, &serviceProperties);
+
+				array_list_pt endpoints = NULL;
+				status = rsa->exportService(rsa->admin, (char*)serviceId, serviceProperties, &endpoints);
+
+				if (status == CELIX_SUCCESS) {
+					hash_map_pt exports = hashMapEntry_getValue(entry);
+
+					if (exports == NULL) {
+						exports = hashMap_create(NULL, NULL, NULL, NULL);
+						hashMap_put(manager->exportedServices,reference,exports);
+					}
+
+					hashMap_put(exports, rsa, endpoints);
+					status = topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints);
+				}
+			}
+
+			hashMapIterator_destroy(exportedServicesIterator);
+
+			celixThreadMutex_unlock(&manager->exportedServicesLock);
+		}
+	}
+	return status;
+}
+
+celix_status_t topologyManager_rsaModified(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	// Nop...
+
+	return status;
+}
+
+celix_status_t topologyManager_rsaRemoved(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	topology_manager_pt manager = (topology_manager_pt) handle;
+	remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service;
+
+	if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
+		hash_map_iterator_pt iter = hashMapIterator_create(manager->exportedServices);
+
+		while (hashMapIterator_hasNext(iter)) {
+
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+			service_reference_pt key = hashMapEntry_getKey(entry);
+			hash_map_pt exports = hashMapEntry_getValue(entry);
+
+			/*
+			 * the problem here is that also the rsa has a a list of
+			 * endpoints which is destroyed when closing the exportRegistration
+			 */
+			array_list_pt exports_list = hashMap_get(exports, rsa);
+
+			if (exports_list != NULL) {
+				int exportsIter = 0;
+				int exportListSize = arrayList_size(exports_list);
+				for (exportsIter = 0; exports_list != NULL && exportsIter < exportListSize; exportsIter++) {
+					export_registration_pt export = arrayList_get(exports_list, exportsIter);
+					topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
+					rsa->exportRegistration_close(rsa->admin, export);
+				}
+			}
+
+			hashMap_remove(exports, rsa);
+			/*if(exports_list!=NULL){
+            	arrayList_destroy(exports_list);
+            }*/
+
+			if (hashMap_size(exports) == 0) {
+				hashMap_remove(manager->exportedServices, key);
+				hashMap_destroy(exports, false, false);
+
+				hashMapIterator_destroy(iter);
+				iter = hashMapIterator_create(manager->exportedServices);
+			}
+		}
+		hashMapIterator_destroy(iter);
+		celixThreadMutex_unlock(&manager->exportedServicesLock);
+	}
+
+	if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
+		hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
+
+		while (hashMapIterator_hasNext(iter)) {
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+			hash_map_pt imports = hashMapEntry_getValue(entry);
+
+			import_registration_pt import = hashMap_get(imports, rsa);
+
+			if (import != NULL) {
+				celix_status_t subStatus = rsa->importRegistration_close(rsa->admin, import);
+
+				if (subStatus == CELIX_SUCCESS) {
+					hashMap_remove(imports, rsa);
+				} else {
+					status = subStatus;
+				}
+			}
+		}
+		hashMapIterator_destroy(iter);
+		celixThreadMutex_unlock(&manager->importedServicesLock);
+	}
+
+	if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
+		arrayList_removeElement(manager->rsaList, rsa);
+		celixThreadMutex_unlock(&manager->rsaListLock);
+	}
+
+	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Removed RSA");
+
+	return status;
+}
+
+
+celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event) {
+	celix_status_t status = CELIX_SUCCESS;
+	service_listener_pt listen = listener;
+	topology_manager_pt manager = listen->handle;
+
+	const char* export = NULL;
+	const char* serviceId = NULL;
+	serviceReference_getProperty(event->reference, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export);
+	serviceReference_getProperty(event->reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+
+	if (!export) {
+		// Nothing needs to be done: we're not interested...
+		return status;
+	}
+
+	switch (event->type) {
+	case OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED:
+		status = topologyManager_addExportedService(manager, event->reference, (char*)serviceId);
+		break;
+	case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED:
+		status = topologyManager_removeExportedService(manager, event->reference, (char*)serviceId);
+
+		if (status == CELIX_SUCCESS) {
+			status = topologyManager_addExportedService(manager, event->reference, (char*)serviceId);
+		}
+		break;
+	case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING:
+		status = topologyManager_removeExportedService(manager, event->reference, (char*)serviceId);
+		break;
+	case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH:
+		break;
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_exportScopeChanged(void *handle, char *filterStr) {
+	celix_status_t status = CELIX_SUCCESS;
+	topology_manager_pt manager = (topology_manager_pt) handle;
+	service_registration_pt reg = NULL;
+	const char* serviceId = NULL;
+	bool found;
+	properties_pt props;
+	filter_pt filter = filter_create(filterStr);
+
+	if (filter == NULL) {
+		printf("filter creating failed\n");
+		return CELIX_ENOMEM;
+	}
+
+	// add already exported services to new rsa
+	if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
+		hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices);
+		int size = hashMap_size(manager->exportedServices);
+		service_reference_pt *srvRefs = (service_reference_pt *) calloc(size, sizeof(service_reference_pt));
+		char **srvIds = (char **) calloc(size, sizeof(char*));
+		int nrFound = 0;
+
+		found = false;
+
+		while (hashMapIterator_hasNext(exportedServicesIterator)) {
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator);
+			service_reference_pt reference = hashMapEntry_getKey(entry);
+			reg = NULL;
+			serviceReference_getServiceRegistration(reference, &reg);
+			if (reg != NULL) {
+				props = NULL;
+				serviceRegistration_getProperties(reg, &props);
+				status = filter_match(filter, props, &found);
+				if (found) {
+					srvRefs[nrFound] = reference;
+					serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+					srvIds[nrFound++] = (char*)serviceId;
+				}
+			}
+		}
+
+		hashMapIterator_destroy(exportedServicesIterator);
+		celixThreadMutex_unlock(&manager->exportedServicesLock);
+
+		if (nrFound > 0) {
+			for (int i = 0; i < nrFound; i++) {
+				// Question: can srvRefs become invalid meanwhile??
+				const char* export = NULL;
+				serviceReference_getProperty(srvRefs[i], (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export);
+
+				if (export) {
+					celix_status_t substatus = topologyManager_removeExportedService(manager, srvRefs[i], srvIds[i]);
+
+					if (substatus != CELIX_SUCCESS) {
+						logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: Removal of exported service (%s) failed.", srvIds[i]);
+					} else {
+						substatus = topologyManager_addExportedService(manager, srvRefs[i], srvIds[i]);
+					}
+
+					if (substatus != CELIX_SUCCESS) {
+						status = substatus;
+					}
+				}
+			}
+		}
+
+		free(srvRefs);
+		free(srvIds);
+	}
+
+	filter_destroy(filter);
+
+	return status;
+}
+
+celix_status_t topologyManager_importScopeChanged(void *handle, char *service_name) {
+	celix_status_t status = CELIX_SUCCESS;
+	endpoint_description_pt endpoint;
+	topology_manager_pt manager = (topology_manager_pt) handle;
+	bool found = false;
+
+	// add already exported services to new rsa
+	if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
+		hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices);
+		while (!found && hashMapIterator_hasNext(importedServicesIterator)) {
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator);
+			endpoint = hashMapEntry_getKey(entry);
+
+			entry = hashMap_getEntry(endpoint->properties, (void *) OSGI_FRAMEWORK_OBJECTCLASS);
+			char* name = (char *) hashMapEntry_getValue(entry);
+			// Test if a service with the same name is imported
+			if (strcmp(name, service_name) == 0) {
+				found = true;
+			}
+		}
+		hashMapIterator_destroy(importedServicesIterator);
+		celixThreadMutex_unlock(&manager->importedServicesLock);
+	}
+
+	if (found) {
+		status = topologyManager_removeImportedService(manager, endpoint, NULL);
+
+		if (status != CELIX_SUCCESS) {
+			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: Removal of imported service (%s; %s) failed.", endpoint->service, endpoint->id);
+		} else {
+			status = topologyManager_addImportedService(manager, endpoint, NULL);
+		}
+	}
+	return status;
+}
+
+celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
+	celix_status_t status = CELIX_SUCCESS;
+	topology_manager_pt manager = handle;
+
+	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add imported service (%s; %s).", endpoint->service, endpoint->id);
+
+	if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
+
+		hash_map_pt imports = hashMap_create(NULL, NULL, NULL, NULL);
+		hashMap_put(manager->importedServices, endpoint, imports);
+
+		if (scope_allowImport(manager->scope, endpoint)) {
+			if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
+				int size = arrayList_size(manager->rsaList);
+
+				for (int iter = 0; iter < size; iter++) {
+					import_registration_pt import = NULL;
+					remote_service_admin_service_pt rsa = arrayList_get(manager->rsaList, iter);
+					celix_status_t substatus = rsa->importService(rsa->admin, endpoint, &import);
+					if (substatus == CELIX_SUCCESS) {
+						hashMap_put(imports, rsa, import);
+					} else {
+						status = substatus;
+					}
+				}
+				celixThreadMutex_unlock(&manager->rsaListLock);
+			}
+
+		}
+
+		celixThreadMutex_unlock(&manager->importedServicesLock);
+	}
+
+
+	return status;
+}
+
+celix_status_t topologyManager_removeImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
+	celix_status_t status = CELIX_SUCCESS;
+	topology_manager_pt manager = handle;
+
+	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", endpoint->service, endpoint->id);
+
+	if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
+
+		hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
+		while (hashMapIterator_hasNext(iter)) {
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+			endpoint_description_pt ep = hashMapEntry_getKey(entry);
+			hash_map_pt imports = hashMapEntry_getValue(entry);
+
+			if (imports != NULL && strcmp(endpoint->id, ep->id) == 0) {
+				hash_map_iterator_pt importsIter = hashMapIterator_create(imports);
+
+				while (hashMapIterator_hasNext(importsIter)) {
+					hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter);
+					remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
+					import_registration_pt import = hashMapEntry_getValue(entry);
+					celix_status_t substatus = rsa->importRegistration_close(rsa->admin, import);
+					if (substatus == CELIX_SUCCESS) {
+						hashMapIterator_remove(importsIter);
+					} else {
+						status = substatus;
+					}
+				}
+				hashMapIterator_destroy(importsIter);
+				hashMapIterator_remove(iter);
+
+				hashMap_destroy(imports, false, false);
+			}
+		}
+		hashMapIterator_destroy(iter);
+		celixThreadMutex_unlock(&manager->importedServicesLock);
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_addExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) {
+	celix_status_t status = CELIX_SUCCESS;
+	properties_pt serviceProperties = NULL;
+
+	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add exported service (%s).", serviceId);
+
+	if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
+		scope_getExportProperties(manager->scope, reference, &serviceProperties);
+		hash_map_pt exports = hashMap_create(NULL, NULL, NULL, NULL);
+		hashMap_put(manager->exportedServices, reference, exports);
+
+		if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
+			int size = arrayList_size(manager->rsaList);
+
+			if (size == 0) {
+				logHelper_log(manager->loghelper, OSGI_LOGSERVICE_WARNING, "TOPOLOGY_MANAGER: No RSA available yet.");
+			}
+
+			for (int iter = 0; iter < size; iter++) {
+				remote_service_admin_service_pt rsa = arrayList_get(manager->rsaList, iter);
+
+				array_list_pt endpoints = NULL;
+				celix_status_t substatus = rsa->exportService(rsa->admin, serviceId, serviceProperties, &endpoints);
+
+				if (substatus == CELIX_SUCCESS) {
+					hashMap_put(exports, rsa, endpoints);
+					topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints);
+				} else {
+					status = substatus;
+				}
+			}
+			celixThreadMutex_unlock(&manager->rsaListLock);
+		}
+		celixThreadMutex_unlock(&manager->exportedServicesLock);
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_removeExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove exported service (%s).", serviceId);
+
+	if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
+		hash_map_pt exports = hashMap_get(manager->exportedServices, reference);
+		if (exports) {
+			hash_map_iterator_pt iter = hashMapIterator_create(exports);
+			while (hashMapIterator_hasNext(iter)) {
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+				remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
+				array_list_pt exportRegistrations = hashMapEntry_getValue(entry);
+
+				int size = arrayList_size(exportRegistrations);
+
+				for (int exportsIter = 0; exportsIter < size; exportsIter++) {
+					export_registration_pt export = arrayList_get(exportRegistrations, exportsIter);
+					topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
+					rsa->exportRegistration_close(rsa->admin, export);
+				}
+
+				hashMap_remove(exports, rsa);
+				//arrayList_destroy(exportRegistrations);
+				hashMapIterator_destroy(iter);
+				iter = hashMapIterator_create(exports);
+
+			}
+			hashMapIterator_destroy(iter);
+		}
+		exports = hashMap_remove(manager->exportedServices, reference);
+
+		if (exports != NULL) {
+			hashMap_destroy(exports, false, false);
+		}
+
+		celixThreadMutex_unlock(&manager->exportedServicesLock);
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_getEndpointDescriptionForExportRegistration(remote_service_admin_service_pt rsa, export_registration_pt export, endpoint_description_pt *endpoint) {
+	celix_status_t status;
+
+	export_reference_pt reference = NULL;
+	status = rsa->exportRegistration_getExportReference(export, &reference);
+
+	if (status == CELIX_SUCCESS) {
+		status = rsa->exportReference_getExportedEndpoint(reference, endpoint);
+	}
+
+	free(reference);
+
+	return status;
+}
+
+celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service) {
+	celix_status_t status = CELIX_SUCCESS;
+	topology_manager_pt manager = (topology_manager_pt) handle;
+
+	bundleContext_getService(manager->context, reference, service);
+
+	return status;
+}
+
+celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) {
+	celix_status_t status = CELIX_SUCCESS;
+	topology_manager_pt manager = handle;
+	const char* scope = NULL;
+
+	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added ENDPOINT_LISTENER");
+
+	if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
+		hashMap_put(manager->listenerList, reference, NULL);
+		celixThreadMutex_unlock(&manager->listenerListLock);
+
+		serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+		filter_pt filter = filter_create(scope);
+		hash_map_iterator_pt refIter = hashMapIterator_create(manager->exportedServices);
+
+		while (hashMapIterator_hasNext(refIter)) {
+			hash_map_pt rsaExports = hashMapIterator_nextValue(refIter);
+			hash_map_iterator_pt rsaIter = hashMapIterator_create(rsaExports);
+
+			while (hashMapIterator_hasNext(rsaIter)) {
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(rsaIter);
+				remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
+				array_list_pt registrations = hashMapEntry_getValue(entry);
+
+				int arrayListSize = arrayList_size(registrations);
+				int cnt = 0;
+
+				for (; cnt < arrayListSize; cnt++) {
+					export_registration_pt export = arrayList_get(registrations, cnt);
+					endpoint_description_pt endpoint = NULL;
+
+					status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
+					if (status == CELIX_SUCCESS) {
+						bool matchResult = false;
+						filter_match(filter, endpoint->properties, &matchResult);
+						if (matchResult) {
+							endpoint_listener_pt listener = (endpoint_listener_pt) service;
+							status = listener->endpointAdded(listener->handle, endpoint, (char*)scope);
+						}
+					}
+				}
+			}
+			hashMapIterator_destroy(rsaIter);
+		}
+		hashMapIterator_destroy(refIter);
+
+		filter_destroy(filter);
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status;
+
+	status = topologyManager_endpointListenerRemoved(handle, reference, service);
+
+	if (status == CELIX_SUCCESS) {
+		status = topologyManager_endpointListenerAdded(handle, reference, service);
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	topology_manager_pt manager = handle;
+
+	if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
+
+		if (hashMap_remove(manager->listenerList, reference)) {
+			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
+		}
+
+		celixThreadMutex_unlock(&manager->listenerListLock);
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
+
+		hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList);
+		while (hashMapIterator_hasNext(iter)) {
+			const char* scope = NULL;
+			endpoint_listener_pt epl = NULL;
+			service_reference_pt reference = hashMapIterator_nextKey(iter);
+
+			serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+			status = bundleContext_getService(manager->context, reference, (void **) &epl);
+			if (status == CELIX_SUCCESS) {
+				filter_pt filter = filter_create(scope);
+
+				int regSize = arrayList_size(registrations);
+				for (int regIt = 0; regIt < regSize; regIt++) {
+					export_registration_pt export = arrayList_get(registrations, regIt);
+					endpoint_description_pt endpoint = NULL;
+					celix_status_t substatus = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
+					if (substatus == CELIX_SUCCESS) {
+						bool matchResult = false;
+						filter_match(filter, endpoint->properties, &matchResult);
+						if (matchResult) {
+							status = epl->endpointAdded(epl->handle, endpoint, (char*)scope);
+						}
+					} else {
+						status = substatus;
+					}
+				}
+				filter_destroy(filter);
+			}
+		}
+		hashMapIterator_destroy(iter);
+		celixThreadMutex_unlock(&manager->listenerListLock);
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
+		hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList);
+		while (hashMapIterator_hasNext(iter)) {
+			endpoint_description_pt endpoint = NULL;
+			endpoint_listener_pt epl = NULL;
+			celix_status_t substatus;
+			const char* scope = NULL;
+
+			service_reference_pt reference = hashMapIterator_nextKey(iter);
+			serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+			substatus = bundleContext_getService(manager->context, reference, (void **) &epl);
+
+			if (substatus == CELIX_SUCCESS) {
+				substatus = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
+			}
+
+			if (substatus == CELIX_SUCCESS) {
+				substatus = epl->endpointRemoved(epl->handle, endpoint, NULL);
+			}
+
+			/*            if (substatus != CELIX_SUCCESS) {
+             status = substatus;
+
+             }
+			 */
+		}
+		hashMapIterator_destroy(iter);
+		celixThreadMutex_unlock(&manager->listenerListLock);
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_extendFilter(topology_manager_pt manager, char *filter, char **updatedFilter) {
+	celix_status_t status;
+	bundle_context_pt context = manager->context;
+	const char* uuid = NULL;
+
+	status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+
+	if (!uuid) {
+		logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!");
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	int len = 10 + strlen(filter) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
+	*updatedFilter = malloc(len);
+	if (!*updatedFilter) {
+		return CELIX_ENOMEM;
+	}
+
+	snprintf(*updatedFilter, len, "(&%s(!(%s=%s)))", filter, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+
+	return status;
+}
+
+celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt listeners) {
+	celix_status_t status = CELIX_SUCCESS;
+	topology_manager_pt manager = handle;
+
+	for (int i = 0; i < arrayList_size(listeners); i++) {
+		listener_hook_info_pt info = arrayList_get(listeners, i);
+		bundle_pt bundle = NULL, self = NULL;
+		bundleContext_getBundle(info->context, &bundle);
+		bundleContext_getBundle(manager->context, &self);
+		if (bundle == self) {
+			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself.");
+			continue;
+		}
+
+		logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" added", info->filter);
+
+		char *filter = NULL;
+		bool free_filter = true;
+		status = topologyManager_extendFilter(manager, info->filter, &filter);
+#if 0
+		if(filter != NULL){
+			// TODO: add status handling
+			status = celixThreadMutex_lock(&manager->importScopesLock);
+
+			struct scope *interest = hashMap_get(manager->importScopes, filter);
+			if (interest) {
+				interest->refs++;
+				free(filter);
+				filter = NULL;
+			} else {
+				interest = malloc(sizeof(*interest));
+				interest->filter = filter;
+				interest->refs = 1;
+				hashMap_put(manager->importScopes, filter, interest);
+				free_filter = false;
+			}
+
+			status = celixThreadMutex_unlock(&manager->importScopesLock);
+		}
+#endif
+
+		if (filter != NULL && free_filter) {
+			free(filter);
+		}
+
+	}
+
+	return status;
+}
+
+celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt listeners) {
+	celix_status_t status = CELIX_SUCCESS;
+	topology_manager_pt manager = handle;
+
+	for (int i = 0; i < arrayList_size(listeners); i++) {
+		listener_hook_info_pt info = arrayList_get(listeners, i);
+
+		bundle_pt bundle = NULL, self = NULL;
+		bundleContext_getBundle(info->context, &bundle);
+		bundleContext_getBundle(manager->context, &self);
+		if (bundle == self) {
+			logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself.");
+			continue;
+		}
+
+		logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" removed.", info->filter);
+
+		char *filter = NULL;
+		topologyManager_extendFilter(manager, info->filter, &filter);
+#if 0
+		status = celixThreadMutex_lock(&manager->importScopesLock);
+
+		struct scope *interest = hashMap_get(manager->importScopes, filter);
+		if (interest != NULL && --interest->refs <= 0) {
+			// last reference, remove from scope
+			hash_map_entry_pt entry = hashMap_getEntry(manager->importScopes, filter);
+			char* key = (char*) hashMapEntry_getKey(entry);
+			interest = hashMap_remove(manager->importScopes, filter);
+			free(key);
+			free(interest);
+		}
+#endif
+
+		if (filter != NULL) {
+			free(filter);
+		}
+#if 0
+		status = celixThreadMutex_unlock(&manager->importScopesLock);
+#endif
+	}
+
+	return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/topology_manager.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/topology_manager.h b/remote_services/topology_manager/src/topology_manager.h
new file mode 100644
index 0000000..7e5e917
--- /dev/null
+++ b/remote_services/topology_manager/src/topology_manager.h
@@ -0,0 +1,65 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * topology_manager.h
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef TOPOLOGY_MANAGER_H_
+#define TOPOLOGY_MANAGER_H_
+
+#include "endpoint_listener.h"
+#include "service_reference.h"
+#include "bundle_context.h"
+#include "log_helper.h"
+#include "scope.h"
+
+#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
+
+typedef struct topology_manager *topology_manager_pt;
+
+celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager, void **scope);
+celix_status_t topologyManager_destroy(topology_manager_pt manager);
+celix_status_t topologyManager_closeImports(topology_manager_pt manager);
+
+celix_status_t topologyManager_rsaAdding(void *handle, service_reference_pt reference, void **service);
+celix_status_t topologyManager_rsaAdded(void *handle, service_reference_pt reference, void *service);
+celix_status_t topologyManager_rsaModified(void *handle, service_reference_pt reference, void *service);
+celix_status_t topologyManager_rsaRemoved(void *handle, service_reference_pt reference, void *service);
+
+celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service);
+celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service);
+celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void* service);
+celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void* service);
+
+celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event);
+
+celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter);
+celix_status_t topologyManager_removeImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter);
+
+celix_status_t topologyManager_addExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId);
+celix_status_t topologyManager_removeExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId);
+
+celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt listeners);
+celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt listeners);
+
+#endif /* TOPOLOGY_MANAGER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/tms_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/CMakeLists.txt b/remote_services/topology_manager/tms_tst/CMakeLists.txt
index dc671e4..6d0713c 100644
--- a/remote_services/topology_manager/tms_tst/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/CMakeLists.txt
@@ -36,10 +36,8 @@ SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}
 add_executable(test_tm_scoped
     run_tests.cpp
     tms_tests.cpp
-    
-   ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
 )
-target_link_libraries(test_tm_scoped Celix::framework ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY} Celix::log_helper)
+target_link_libraries(test_tm_scoped Celix::framework ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY} Celix::log_helper remote_service_admin_common)
 
 add_dependencies(test_tm_scoped remote_service_admin_dfi topology_manager calculator)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
index 9e36e4c..fc9d9bf 100644
--- a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
@@ -32,4 +32,4 @@ bundle_files(topology_manager_test_bundle
     DESTINATION .
 )
 
-target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY})
+target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY} remote_service_admin calculator_api)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
index b961de7..bfd7fc1 100644
--- a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
@@ -15,14 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories(
-        ${CPPUTEST_INCLUDE_DIR}
-        ${PROJECT_SOURCE_DIR}/framework/public/include
-        ${PROJECT_SOURCE_DIR}/utils/public/include
-        ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/include
-)
-
-
 add_bundle(topology_manager_disc_mock_bundle
     VERSION 0.0.1
     SOURCES
@@ -30,4 +22,5 @@ add_bundle(topology_manager_disc_mock_bundle
         disc_mock_service.c
 
 )
-target_link_libraries(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::framework)
+target_include_directories(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_INCLUDE_DIR})
+target_link_libraries(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::framework discovery_common)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/utils/private/include/civetweb.h
----------------------------------------------------------------------
diff --git a/remote_services/utils/private/include/civetweb.h b/remote_services/utils/private/include/civetweb.h
deleted file mode 100644
index 61a8e98..0000000
--- a/remote_services/utils/private/include/civetweb.h
+++ /dev/null
@@ -1,657 +0,0 @@
-/* Copyright (c) 2013-2014 the Civetweb developers
- * Copyright (c) 2004-2013 Sergey Lyubka
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef CIVETWEB_HEADER_INCLUDED
-#define CIVETWEB_HEADER_INCLUDED
-
-#ifndef CIVETWEB_VERSION
-#define CIVETWEB_VERSION "1.7"
-#endif
-
-#ifndef CIVETWEB_API
-    #if defined(_WIN32)
-        #if defined(CIVETWEB_DLL_EXPORTS)
-            #define CIVETWEB_API __declspec(dllexport)
-        #elif defined(CIVETWEB_DLL_IMPORTS)
-            #define CIVETWEB_API __declspec(dllimport)
-        #else
-            #define CIVETWEB_API
-        #endif
-    #else
-        #define CIVETWEB_API
-    #endif
-#endif
-
-#include <stdio.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-struct mg_context;     /* Handle for the HTTP service itself */
-struct mg_connection;  /* Handle for the individual connection */
-
-
-/* This structure contains information about the HTTP request. */
-struct mg_request_info {
-    const char *request_method; /* "GET", "POST", etc */
-    const char *uri;            /* URL-decoded URI */
-    const char *http_version;   /* E.g. "1.0", "1.1" */
-    const char *query_string;   /* URL part after '?', not including '?', or
-                                   NULL */
-    const char *remote_user;    /* Authenticated user, or NULL if no auth
-                                   used */
-    char remote_addr[48];       /* Client's IP address as a string. */
-    long remote_ip;             /* Client's IP address. Deprecated: use remote_addr instead */
-
-    long long content_length;   /* Length (in bytes) of the request body,
-                                   can be -1 if no length was given. */
-    int remote_port;            /* Client's port */
-    int is_ssl;                 /* 1 if SSL-ed, 0 if not */
-    void *user_data;            /* User data pointer passed to mg_start() */
-    void *conn_data;            /* Connection-specific user data */
-
-    int num_headers;            /* Number of HTTP headers */
-    struct mg_header {
-        const char *name;       /* HTTP header name */
-        const char *value;      /* HTTP header value */
-    } http_headers[64];         /* Maximum 64 headers */
-};
-
-
-/* This structure needs to be passed to mg_start(), to let civetweb know
-   which callbacks to invoke. For a detailed description, see
-   https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md */
-struct mg_callbacks {
-    /* Called when civetweb has received new HTTP request.
-       If the callback returns one, it must process the request
-       by sending valid HTTP headers and a body. Civetweb will not do
-       any further processing. Otherwise it must return zero.
-       Note that since V1.7 the "begin_request" function is called
-       before an authorization check. If an authorization check is
-       required, use a request_handler instead.
-       Return value:
-         0: civetweb will process the request itself. In this case,
-            the callback must not send any data to the client.
-         1: callback already processed the request. Civetweb will
-            not send any data after the callback returned. */
-    int  (*begin_request)(struct mg_connection *);
-
-    /* Called when civetweb has finished processing request. */
-    void (*end_request)(const struct mg_connection *, int reply_status_code);
-
-    /* Called when civetweb is about to log a message. If callback returns
-       non-zero, civetweb does not log anything. */
-    int  (*log_message)(const struct mg_connection *, const char *message);
-
-    /* Called when civetweb initializes SSL library.
-       Parameters:
-         user_data: parameter user_data passed when starting the server.
-       Return value:
-         0: civetweb will set up the SSL certificate.
-         1: civetweb assumes the callback already set up the certificate.
-        -1: initializing ssl fails. */
-    int  (*init_ssl)(void *ssl_context, void *user_data);
-
-    /* Called when websocket request is received, before websocket handshake.
-       Return value:
-         0: civetweb proceeds with websocket handshake.
-         1: connection is closed immediately. */
-    int (*websocket_connect)(const struct mg_connection *);
-
-    /* Called when websocket handshake is successfully completed, and
-       connection is ready for data exchange. */
-    void (*websocket_ready)(struct mg_connection *);
-
-    /* Called when data frame has been received from the client.
-       Parameters:
-         bits: first byte of the websocket frame, see websocket RFC at
-               http://tools.ietf.org/html/rfc6455, section 5.2
-         data, data_len: payload, with mask (if any) already applied.
-       Return value:
-         1: keep this websocket connection open.
-         0: close this websocket connection. */
-    int  (*websocket_data)(struct mg_connection *, int bits,
-                           char *data, size_t data_len);
-
-    /* Called when civetweb is closing a connection.  The per-context mutex is
-       locked when this is invoked.  This is primarily useful for noting when
-       a websocket is closing and removing it from any application-maintained
-       list of clients. */
-    void (*connection_close)(struct mg_connection *);
-
-    /* Called when civetweb tries to open a file. Used to intercept file open
-       calls, and serve file data from memory instead.
-       Parameters:
-          path:     Full path to the file to open.
-          data_len: Placeholder for the file size, if file is served from
-                    memory.
-       Return value:
-         NULL: do not serve file from memory, proceed with normal file open.
-         non-NULL: pointer to the file contents in memory. data_len must be
-           initilized with the size of the memory block. */
-    const char * (*open_file)(const struct mg_connection *,
-                              const char *path, size_t *data_len);
-
-    /* Called when civetweb is about to serve Lua server page, if
-       Lua support is enabled.
-       Parameters:
-         lua_context: "lua_State *" pointer. */
-    void (*init_lua)(struct mg_connection *, void *lua_context);
-
-    /* Called when civetweb has uploaded a file to a temporary directory as a
-       result of mg_upload() call.
-       Parameters:
-         file_name: full path name to the uploaded file. */
-    void (*upload)(struct mg_connection *, const char *file_name);
-
-    /* Called when civetweb is about to send HTTP error to the client.
-       Implementing this callback allows to create custom error pages.
-       Parameters:
-         status: HTTP error status code.
-       Return value:
-         1: run civetweb error handler.
-         0: callback already handled the error. */
-    int  (*http_error)(struct mg_connection *, int status);
-
-    /* Called after civetweb context has been created, before requests
-       are processed.
-       Parameters:
-         ctx: context handle */
-    void (*init_context)(struct mg_context * ctx);
-
-    /* Called when civetweb context is deleted.
-       Parameters:
-         ctx: context handle */
-    void (*exit_context)(struct mg_context * ctx);
-};
-
-
-/* Start web server.
-
-   Parameters:
-     callbacks: mg_callbacks structure with user-defined callbacks.
-     options: NULL terminated list of option_name, option_value pairs that
-              specify Civetweb configuration parameters.
-
-   Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
-      processing is required for these, signal handlers must be set up
-      after calling mg_start().
-
-
-   Example:
-     const char *options[] = {
-       "document_root", "/var/www",
-       "listening_ports", "80,443s",
-       NULL
-     };
-     struct mg_context *ctx = mg_start(&my_func, NULL, options);
-
-   Refer to https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md
-   for the list of valid option and their possible values.
-
-   Return:
-     web server context, or NULL on error. */
-CIVETWEB_API struct mg_context *mg_start(const struct mg_callbacks *callbacks,
-                            void *user_data,
-                            const char **configuration_options);
-
-
-/* Stop the web server.
-
-   Must be called last, when an application wants to stop the web server and
-   release all associated resources. This function blocks until all Civetweb
-   threads are stopped. Context pointer becomes invalid. */
-CIVETWEB_API void mg_stop(struct mg_context *);
-
-
-/* mg_request_handler
-
-   Called when a new request comes in.  This callback is URI based
-   and configured with mg_set_request_handler().
-
-   Parameters:
-      conn: current connection information.
-      cbdata: the callback data configured with mg_set_request_handler().
-   Returns:
-      0: the handler could not handle the request, so fall through.
-      1: the handler processed the request. */
-typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata);
-
-
-/* mg_set_request_handler
-
-   Sets or removes a URI mapping for a request handler.
-
-   URI's are ordered and prefixed URI's are supported. For example,
-   consider two URIs: /a/b and /a
-           /a   matches /a
-           /a/b matches /a/b
-           /a/c matches /a
-
-   Parameters:
-      ctx: server context
-      uri: the URI to configure
-      handler: the callback handler to use when the URI is requested.
-               If NULL, the URI will be removed.
-      cbdata: the callback data to give to the handler when it s requested. */
-CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata);
-
-
-/* Get the value of particular configuration parameter.
-   The value returned is read-only. Civetweb does not allow changing
-   configuration at run time.
-   If given parameter name is not valid, NULL is returned. For valid
-   names, return value is guaranteed to be non-NULL. If parameter is not
-   set, zero-length string is returned. */
-CIVETWEB_API const char *mg_get_option(const struct mg_context *ctx, const char *name);
-
-
-/* Get context from connection. */
-CIVETWEB_API struct mg_context *mg_get_context(struct mg_connection *conn);
-
-
-/* Get user data passed to mg_start from context. */
-CIVETWEB_API void *mg_get_user_data(struct mg_context *ctx);
-
-
-#if defined(MG_LEGACY_INTERFACE)
-/* Return array of strings that represent valid configuration options.
-   For each option, option name and default value is returned, i.e. the
-   number of entries in the array equals to number_of_options x 2.
-   Array is NULL terminated. */
-/* Deprecated: Use mg_get_valid_options instead. */
-CIVETWEB_API const char **mg_get_valid_option_names(void);
-#endif
-
-
-struct mg_option {
-    const char * name;
-    int type;
-    const char * default_value;
-};
-
-enum {
-    CONFIG_TYPE_UNKNOWN = 0x0,
-    CONFIG_TYPE_NUMBER = 0x1,
-    CONFIG_TYPE_STRING = 0x2,
-    CONFIG_TYPE_FILE = 0x3,
-    CONFIG_TYPE_DIRECTORY = 0x4,
-    CONFIG_TYPE_BOOLEAN = 0x5,
-    CONFIG_TYPE_EXT_PATTERN = 0x6
-};
-
-
-/* Return array of struct mg_option, representing all valid configuration
-   options of civetweb.c.
-   The array is terminated by a NULL name option. */
-CIVETWEB_API const struct mg_option *mg_get_valid_options(void);
-
-
-/* Get the list of ports that civetweb is listening on.
-   size is the size of the ports int array and ssl int array to fill.
-   It is the caller's responsibility to make sure ports and ssl each
-   contain at least size int elements worth of memory to write into.
-   Return value is the number of ports and ssl information filled in.
-   The value returned is read-only. Civetweb does not allow changing
-   configuration at run time. */
-CIVETWEB_API size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl);
-
-
-/* Add, edit or delete the entry in the passwords file.
-
-   This function allows an application to manipulate .htpasswd files on the
-   fly by adding, deleting and changing user records. This is one of the
-   several ways of implementing authentication on the server side. For another,
-   cookie-based way please refer to the examples/chat in the source tree.
-
-   If password is not NULL, entry is added (or modified if already exists).
-   If password is NULL, entry is deleted.
-
-   Return:
-     1 on success, 0 on error. */
-CIVETWEB_API int mg_modify_passwords_file(const char *passwords_file_name,
-                                          const char *domain,
-                                          const char *user,
-                                          const char *password);
-
-
-/* Return information associated with the request. */
-CIVETWEB_API struct mg_request_info *mg_get_request_info(struct mg_connection *);
-
-
-/* Send data to the client.
-   Return:
-    0   when the connection has been closed
-    -1  on error
-    >0  number of bytes written on success */
-CIVETWEB_API int mg_write(struct mg_connection *, const void *buf, size_t len);
-
-
-/* Send data to a websocket client wrapped in a websocket frame.  Uses mg_lock
-   to ensure that the transmission is not interrupted, i.e., when the
-   application is proactively communicating and responding to a request
-   simultaneously.
-
-   Send data to a websocket client wrapped in a websocket frame.
-   This function is available when civetweb is compiled with -DUSE_WEBSOCKET
-
-   Return:
-    0   when the connection has been closed
-    -1  on error
-    >0  number of bytes written on success */
-CIVETWEB_API int mg_websocket_write(struct mg_connection* conn, int opcode,
-                                    const char *data, size_t data_len);
-
-
-/* Blocks until unique access is obtained to this connection. Intended for use
-   with websockets only.
-   Invoke this before mg_write or mg_printf when communicating with a
-   websocket if your code has server-initiated communication as well as
-   communication in direct response to a message. */
-CIVETWEB_API void mg_lock_connection(struct mg_connection* conn);
-CIVETWEB_API void mg_unlock_connection(struct mg_connection* conn);
-
-#if defined(MG_LEGACY_INTERFACE)
-#define mg_lock mg_lock_connection
-#define mg_unlock mg_unlock_connection
-#endif
-
-/* Lock server context.  This lock may be used to protect ressources
-   that are shared between different connection/worker threads. */
-CIVETWEB_API void mg_lock_context(struct mg_context* ctx);
-CIVETWEB_API void mg_unlock_context(struct mg_context* ctx);
-
-
-/* Opcodes, from http://tools.ietf.org/html/rfc6455 */
-enum {
-    WEBSOCKET_OPCODE_CONTINUATION = 0x0,
-    WEBSOCKET_OPCODE_TEXT = 0x1,
-    WEBSOCKET_OPCODE_BINARY = 0x2,
-    WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
-    WEBSOCKET_OPCODE_PING = 0x9,
-    WEBSOCKET_OPCODE_PONG = 0xa
-};
-
-
-/* Macros for enabling compiler-specific checks forprintf-like arguments. */
-#undef PRINTF_FORMAT_STRING
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-#include <sal.h>
-#if defined(_MSC_VER) && _MSC_VER > 1400
-#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
-#else
-#define PRINTF_FORMAT_STRING(s) __format_string s
-#endif
-#else
-#define PRINTF_FORMAT_STRING(s) s
-#endif
-
-#ifdef __GNUC__
-#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
-#else
-#define PRINTF_ARGS(x, y)
-#endif
-
-/* Send data to the client usingprintf() semantics.
-   Works exactly like mg_write(), but allows to do message formatting. */
-CIVETWEB_API int mg_printf(struct mg_connection *,
-                           PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
-
-
-/* Send contents of the entire file together with HTTP headers. */
-CIVETWEB_API void mg_send_file(struct mg_connection *conn, const char *path);
-
-
-/* Read data from the remote end, return number of bytes read.
-   Return:
-     0     connection has been closed by peer. No more data could be read.
-     < 0   read error. No more data could be read from the connection.
-     > 0   number of bytes read into the buffer. */
-CIVETWEB_API int mg_read(struct mg_connection *, void *buf, size_t len);
-
-
-/* Get the value of particular HTTP header.
-
-   This is a helper function. It traverses request_info->http_headers array,
-   and if the header is present in the array, returns its value. If it is
-   not present, NULL is returned. */
-CIVETWEB_API const char *mg_get_header(const struct mg_connection *, const char *name);
-
-
-/* Get a value of particular form variable.
-
-   Parameters:
-     data: pointer to form-uri-encoded buffer. This could be either POST data,
-           or request_info.query_string.
-     data_len: length of the encoded data.
-     var_name: variable name to decode from the buffer
-     dst: destination buffer for the decoded variable
-     dst_len: length of the destination buffer
-
-   Return:
-     On success, length of the decoded variable.
-     On error:
-        -1 (variable not found).
-        -2 (destination buffer is NULL, zero length or too small to hold the
-            decoded variable).
-
-   Destination buffer is guaranteed to be '\0' - terminated if it is not
-   NULL or zero length. */
-CIVETWEB_API int mg_get_var(const char *data, size_t data_len,
-                            const char *var_name, char *dst, size_t dst_len);
-
-
-/* Get a value of particular form variable.
-
-   Parameters:
-     data: pointer to form-uri-encoded buffer. This could be either POST data,
-           or request_info.query_string.
-     data_len: length of the encoded data.
-     var_name: variable name to decode from the buffer
-     dst: destination buffer for the decoded variable
-     dst_len: length of the destination buffer
-     occurrence: which occurrence of the variable, 0 is the first, 1 the
-                 second...
-                this makes it possible to parse a query like
-                b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
-
-   Return:
-     On success, length of the decoded variable.
-     On error:
-        -1 (variable not found).
-        -2 (destination buffer is NULL, zero length or too small to hold the
-            decoded variable).
-
-   Destination buffer is guaranteed to be '\0' - terminated if it is not
-   NULL or zero length. */
-CIVETWEB_API int mg_get_var2(const char *data, size_t data_len,
-                             const char *var_name, char *dst, size_t dst_len, size_t occurrence);
-
-
-/* Fetch value of certain cookie variable into the destination buffer.
-
-   Destination buffer is guaranteed to be '\0' - terminated. In case of
-   failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
-   parameter. This function returns only first occurrence.
-
-   Return:
-     On success, value length.
-     On error:
-        -1 (either "Cookie:" header is not present at all or the requested
-            parameter is not found).
-        -2 (destination buffer is NULL, zero length or too small to hold the
-            value). */
-CIVETWEB_API int mg_get_cookie(const char *cookie, const char *var_name,
-                               char *buf, size_t buf_len);
-
-
-/* Download data from the remote web server.
-     host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
-     port: port number, e.g. 80.
-     use_ssl: wether to use SSL connection.
-     error_buffer, error_buffer_size: error message placeholder.
-     request_fmt,...: HTTP request.
-   Return:
-     On success, valid pointer to the new connection, suitable for mg_read().
-     On error, NULL. error_buffer contains error message.
-   Example:
-     char ebuf[100];
-     struct mg_connection *conn;
-     conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
-                        "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
- */
-CIVETWEB_API struct mg_connection *mg_download(const char *host, int port, int use_ssl,
-                                               char *error_buffer, size_t error_buffer_size,
-                                               PRINTF_FORMAT_STRING(const char *request_fmt),
-                                               ...) PRINTF_ARGS(6, 7);
-
-
-/* Close the connection opened by mg_download(). */
-CIVETWEB_API void mg_close_connection(struct mg_connection *conn);
-
-
-/* File upload functionality. Each uploaded file gets saved into a temporary
-   file and MG_UPLOAD event is sent.
-   Return number of uploaded files. */
-CIVETWEB_API int mg_upload(struct mg_connection *conn, const char *destination_dir);
-
-
-/* Convenience function -- create detached thread.
-   Return: 0 on success, non-0 on error. */
-typedef void * (*mg_thread_func_t)(void *);
-CIVETWEB_API int mg_start_thread(mg_thread_func_t f, void *p);
-
-
-/* Return builtin mime type for the given file name.
-   For unrecognized extensions, "text/plain" is returned. */
-CIVETWEB_API const char *mg_get_builtin_mime_type(const char *file_name);
-
-
-/* Return Civetweb version. */
-CIVETWEB_API const char *mg_version(void);
-
-
-/* URL-decode input buffer into destination buffer.
-   0-terminate the destination buffer.
-   form-url-encoded data differs from URI encoding in a way that it
-   uses '+' as character for space, see RFC 1866 section 8.2.1
-   http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
-   Return: length of the decoded data, or -1 if dst buffer is too small. */
-CIVETWEB_API int mg_url_decode(const char *src, int src_len, char *dst,
-                               int dst_len, int is_form_url_encoded);
-
-
-/* URL-encode input buffer into destination buffer.
-   returns the length of the resulting buffer or -1
-   is the buffer is too small. */
-CIVETWEB_API int mg_url_encode(const char *src, char *dst, size_t dst_len);
-
-
-/* MD5 hash given strings.
-   Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
-   ASCIIz strings. When function returns, buf will contain human-readable
-   MD5 hash. Example:
-     char buf[33];
-     mg_md5(buf, "aa", "bb", NULL); */
-CIVETWEB_API char *mg_md5(char buf[33], ...);
-
-
-/* Print error message to the opened error log stream.
-   This utilizes the provided logging configuration.
-     conn: connection
-     fmt: format string without the line return
-     ...: variable argument list
-   Example:
-     mg_cry(conn,"i like %s", "logging"); */
-CIVETWEB_API void mg_cry(struct mg_connection *conn,
-                         PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
-
-
-/* utility method to compare two buffers, case incensitive. */
-CIVETWEB_API int mg_strncasecmp(const char *s1, const char *s2, size_t len);
-
-/* Connect to a websocket as a client
-   Parameters:
-     host: host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost"
-     port: server port
-     use_ssl: make a secure connection to server
-     error_buffer, error_buffer_size: buffer for an error message
-     path: server path you are trying to connect to, i.e. if connection to localhost/app, path should be "/app"
-     origin: value of the Origin HTTP header
-     data_func: callback that should be used when data is received from the server
-     user_data: user supplied argument
-
-   Return:
-     On success, valid mg_connection object.
-     On error, NULL. Se error_buffer for details.
-*/
-
-typedef int  (*websocket_data_func)(struct mg_connection *, int bits,
-                           char *data, size_t data_len);
-
-typedef void (*websocket_close_func)(struct mg_connection *);
-
-CIVETWEB_API struct mg_connection *mg_connect_websocket_client(const char *host, int port, int use_ssl,
-                                               char *error_buffer, size_t error_buffer_size,
-                                               const char *path, const char *origin,
-                                               websocket_data_func data_func, websocket_close_func close_func,
-                                               void * user_data);
-
-/* Connect to a TCP server as a client (can be used to connect to a HTTP server)
-   Parameters:
-     host: host to connect to, i.e. "www.wikipedia.org" or "192.168.1.1" or "localhost"
-     port: server port
-     use_ssl: make a secure connection to server
-     error_buffer, error_buffer_size: buffer for an error message
-
-   Return:
-     On success, valid mg_connection object.
-     On error, NULL. Se error_buffer for details.
-*/
-CIVETWEB_API struct mg_connection *mg_connect_client(const char *host, int port, int use_ssl,
-                                               char *error_buffer, size_t error_buffer_size);
-
-
-enum {
-    TIMEOUT_INFINITE = -1
-};
-
-/* Wait for a response from the server
-   Parameters:
-     conn: connection
-     ebuf, ebuf_len: error message placeholder.
-     timeout: time to wait for a response in milliseconds (if < 0 then wait forever)
-
-   Return:
-     On success, >= 0
-     On error/timeout, < 0
-*/
-CIVETWEB_API int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CIVETWEB_HEADER_INCLUDED */


[08/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/private/src/export_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/src/export_registration_impl.c b/remote_services/remote_service_admin/private/src/export_registration_impl.c
deleted file mode 100644
index 1c684e7..0000000
--- a/remote_services/remote_service_admin/private/src/export_registration_impl.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * export_registration_impl.c
- *
- *  \date       Oct 6, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdlib.h>
-
-#include "constants.h"
-
-#include "celix_errno.h"
-
-#include "export_registration_impl.h"
-#include "remote_service_admin_impl.h"
-
-
-struct export_reference {
-	endpoint_description_pt endpoint;
-	service_reference_pt reference;
-};
-
-celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service);
-celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *service);
-celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service);
-celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service);
-
-celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker);
-
-celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*registration = calloc(1, sizeof(**registration));
-	if (!*registration) {
-		status = CELIX_ENOMEM;
-	} else {
-		(*registration)->context = context;
-		(*registration)->closed = false;
-		(*registration)->endpointDescription = endpoint;
-		(*registration)->reference = reference;
-		(*registration)->rsa = rsa;
-		(*registration)->tracker = NULL;
-		(*registration)->endpoint = NULL;
-		(*registration)->endpointTracker = NULL;
-		(*registration)->exportReference = NULL;
-		(*registration)->bundle = NULL;
-		(*registration)->loghelper = helper;
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_destroy(export_registration_pt *registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	remoteServiceAdmin_destroyEndpointDescription(&(*registration)->endpointDescription);
-	free(*registration);
-
-	return status;
-}
-
-celix_status_t exportRegistration_startTracking(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (registration->endpointTracker == NULL) {
-		status = exportRegistration_createEndpointTracker(registration, &registration->endpointTracker);
-		if (status == CELIX_SUCCESS) {
-			status = serviceTracker_open(registration->endpointTracker);
-		}
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_stopTracking(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (registration->endpointTracker != NULL) {
-		status = serviceTracker_close(registration->endpointTracker);
-		if (status != CELIX_SUCCESS) {
-		    logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close endpoint tracker");
-		}
-		else {
-			status = serviceTracker_destroy(registration->endpointTracker);
-		}
-	}
-	if (registration->tracker != NULL) {
-		status = serviceTracker_close(registration->tracker);
-		if (status != CELIX_SUCCESS) {
-			logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close service tracker");
-		}
-		else {
-			status = serviceTracker_destroy(registration->tracker);
-		}
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker) {
-	celix_status_t status;
-
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(registration, exportRegistration_endpointAdding,
-			exportRegistration_endpointAdded, exportRegistration_endpointModified, exportRegistration_endpointRemoved, &customizer);
-
-	if (status == CELIX_SUCCESS) {
-		char filter[512];
-
-		snprintf(filter, 512, "(&(%s=%s)(remote.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_ENDPOINT, registration->endpointDescription->service);
-		status = serviceTracker_createWithFilter(registration->context, filter, customizer, tracker);
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service) {
-	celix_status_t status;
-	export_registration_pt registration = handle;
-
-	status = bundleContext_getService(registration->context, reference, service);
-
-	return status;
-}
-
-celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *endpoint_service) {
-	celix_status_t status = CELIX_SUCCESS;
-	export_registration_pt registration = handle;
-
-	remote_endpoint_service_pt endpoint = endpoint_service;
-	if (registration->endpoint == NULL) {
-		registration->endpoint = endpoint;
-		void *service = NULL;
-		status = bundleContext_getService(registration->context, registration->reference, &service);
-		if (status == CELIX_SUCCESS) {
-			endpoint->setService(endpoint->endpoint, service);
-		}
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	return status;
-}
-
-celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-	export_registration_pt registration = handle;
-
-	remote_endpoint_service_pt endpoint = service;
-	if (registration->endpoint != NULL) {
-		endpoint->setService(endpoint->endpoint, NULL);
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_open(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-	const char *bundleStore = NULL;
-
-	bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
-
-	if (bundleStore == NULL) {
-		bundleStore = DEFAULT_BUNDLE_STORE;
-	}
-	char name[256];
-
-	snprintf(name, 256, "%s/%s_endpoint.zip", bundleStore, registration->endpointDescription->service);
-
-	status = bundleContext_installBundle(registration->context, name, &registration->bundle);
-	if (status == CELIX_SUCCESS) {
-		status = bundle_start(registration->bundle);
-		if (status == CELIX_SUCCESS) {
-		}
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_close(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	exportRegistration_stopTracking(registration);
-
-	bundle_uninstall(registration->bundle);
-
-
-	return status;
-}
-
-celix_status_t exportRegistration_getException(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	registration->exportReference = calloc(1, sizeof(*registration->exportReference));
-
-	if (registration->exportReference == NULL) {
-		status = CELIX_ENOMEM;
-	} else {
-		registration->exportReference->endpoint = registration->endpointDescription;
-		registration->exportReference->reference = registration->reference;
-	}
-	
-	*reference = registration->exportReference;
-
-	return status;
-}
-
-celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	registration->endpointDescription = endpointDescription;
-
-	return status;
-}
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*endpoint = reference->endpoint;
-
-	return status;
-}
-
-celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service) {
-	celix_status_t status = CELIX_SUCCESS;
-	*service = reference->reference;
-	return status;
-}
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/private/src/import_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/src/import_registration_impl.c b/remote_services/remote_service_admin/private/src/import_registration_impl.c
deleted file mode 100644
index 9a84327..0000000
--- a/remote_services/remote_service_admin/private/src/import_registration_impl.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * import_registration_impl.c
- *
- *  \date       Oct 14, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <constants.h>
-
-#include "celix_errno.h"
-
-#include "import_registration_impl.h"
-#include "remote_service_admin_impl.h"
-
-struct import_reference {
-	endpoint_description_pt endpoint;
-	service_reference_pt reference;
-};
-
-
-
-celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service);
-celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service);
-celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service);
-celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service);
-
-celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle sendToCallback, bundle_context_pt context, import_registration_pt *registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*registration = calloc(1, sizeof(**registration));
-	if (!*registration) {
-		status = CELIX_ENOMEM;
-	} else {
-		(*registration)->context = context;
-		(*registration)->closed = false;
-		(*registration)->endpointDescription = endpoint;
-		(*registration)->rsa = rsa;
-		(*registration)->sendToCallback = sendToCallback;
-		(*registration)->reference = NULL;
-		(*registration)->importReference = NULL;
-	}
-
-	return status;
-}
-
-celix_status_t importRegistration_destroy(import_registration_pt registration)
-{
-	free(registration);
-
-	return CELIX_SUCCESS;
-}
-
-
-celix_status_t importRegistrationFactory_create(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*registration_factory = calloc(1, sizeof(**registration_factory));
-	if (!*registration_factory) {
-		status = CELIX_ENOMEM;
-	} else {
-		(*registration_factory)->serviceName = strdup(serviceName);
-		(*registration_factory)->context = context;
-		(*registration_factory)->bundle = NULL;
-		(*registration_factory)->loghelper = helper;
-
-		arrayList_create(&(*registration_factory)->registrations);
-	}
-
-	return status;
-}
-
-
-
-celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (*registration_factory != NULL)
-	{
-		free((*registration_factory)->serviceName);
-		arrayList_destroy((*registration_factory)->registrations);
-
-		serviceTracker_destroy((*registration_factory)->proxyFactoryTracker);
-		free(*registration_factory);
-
-		*registration_factory = NULL;
-	}
-
-
-	return status;
-}
-
-
-celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory)
-{
-	celix_status_t status;
-
-	const char *bundleStore = NULL;
-	bundleContext_getProperty(registration_factory->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
-
-	if (bundleStore == NULL) {
-		bundleStore = DEFAULT_BUNDLE_STORE;
-	}
-
-	char name[256];
-	snprintf(name, 256, "%s/%s_proxy.zip", bundleStore, registration_factory->serviceName);
-
-	status = bundleContext_installBundle(registration_factory->context, name, &registration_factory->bundle);
-
-	if (status == CELIX_SUCCESS) {
-		status = bundle_start(registration_factory->bundle);
-		if (status == CELIX_SUCCESS) {
-			logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_INFO, "%s successfully started.", name);
-		}
-	}
-	else {
-		logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_ERROR, "%s could not be installed.", name);
-	}
-
-	return status;
-}
-
-celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory)
-{
-	celix_status_t status = CELIX_SUCCESS;
-
-
-	if (registration_factory->proxyFactoryTracker != NULL) {
-		serviceTracker_close(registration_factory->proxyFactoryTracker);
-	}
-
-	if (registration_factory->bundle != NULL) {
-		bundle_uninstall(registration_factory->bundle);
-	}
-
-	return status;
-}
-
-
-celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker) {
-	celix_status_t status;
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(registration_factory, importRegistration_proxyFactoryAdding, importRegistration_proxyFactoryAdded, importRegistration_proxyFactoryModified, importRegistration_proxyFactoryRemoved, &customizer);
-
-	if (status == CELIX_SUCCESS) {
-		char filter[512];
-
-		snprintf(filter, 512, "(&(%s=%s)(proxy.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_PROXY_FACTORY, registration_factory->serviceName);
-		status = serviceTracker_createWithFilter(registration_factory->context, filter, customizer, tracker);
-
-		if (status == CELIX_SUCCESS)
-		{
-			serviceTracker_open(*tracker);
-		}
-	}
-
-	return status;
-}
-
-celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service) {
-	celix_status_t status = CELIX_SUCCESS;
-	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
-
-	bundleContext_getService(registration_factory->context, reference, service);
-
-	return status;
-}
-
-celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
-	registration_factory->trackedFactory = (remote_proxy_factory_service_pt) service;
-
-	return status;
-}
-
-celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	return status;
-}
-
-celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
-	registration_factory->trackedFactory = NULL;
-
-	return status;
-}
-
-
-
-celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory)
-{
-	celix_status_t status;
-
-	if ( (status = importRegistrationFactory_create(helper, serviceName, context, registration_factory)) == CELIX_SUCCESS) {
-		// starting the proxy tracker first allows us to pick up already available proxy factories
-		importRegistration_createProxyFactoryTracker(*registration_factory, &((*registration_factory)->proxyFactoryTracker));
-		logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_INFO, "remoteServiceAdmin_importService: new registration_factory added for %s at %p", serviceName, (*registration_factory)->proxyFactoryTracker);
-
-		// check whether factory is available
-		if (((*registration_factory)->trackedFactory == NULL) && ((status = importRegistrationFactory_open(*registration_factory)) != CELIX_SUCCESS)) {
-			logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_ERROR, "remoteServiceAdmin_importService: cannot open registration_factory for %s.", serviceName);
-
-			importRegistrationFactory_close(*registration_factory);
-			importRegistrationFactory_destroy(registration_factory);
-		}
-	}
-
-	return status;
-}
-
-
-
-
-celix_status_t importRegistration_getException(import_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-
-celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (registration->importReference == NULL) {
-		registration->importReference = calloc(1, sizeof(*registration->importReference));
-		if (registration->importReference == NULL) {
-			status = CELIX_ENOMEM;
-		} else {
-			registration->importReference->endpoint = registration->endpointDescription;
-			registration->importReference->reference = registration->reference;
-		}
-	}
-
-	*reference = registration->importReference;
-
-	return status;
-}
-
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-celix_status_t importReference_getImportedService(import_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/private/src/remote_proxy_factory_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/src/remote_proxy_factory_impl.c b/remote_services/remote_service_admin/private/src/remote_proxy_factory_impl.c
deleted file mode 100644
index 9f996d6..0000000
--- a/remote_services/remote_service_admin/private/src/remote_proxy_factory_impl.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0 
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * remote_proxy_factory_impl.c
- *
- *  \date       22 Dec 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "remote_proxy.h"
-
-typedef struct proxy_instance {
-	service_registration_pt registration_ptr;
-	void *service;
-	properties_pt properties;
-} *proxy_instance_pt;
-
-static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback);
-static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription);
-
-celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
-		createProxyService create, destroyProxyService destroy,
-		remote_proxy_factory_pt *remote_proxy_factory_ptr) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*remote_proxy_factory_ptr = calloc(1, sizeof(**remote_proxy_factory_ptr));
-	if (!*remote_proxy_factory_ptr) {
-		status = CELIX_ENOMEM;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		(*remote_proxy_factory_ptr)->context_ptr = context;
-		(*remote_proxy_factory_ptr)->service = strdup(service);
-
-		(*remote_proxy_factory_ptr)->remote_proxy_factory_service_ptr = NULL;
-		(*remote_proxy_factory_ptr)->properties = NULL;
-		(*remote_proxy_factory_ptr)->registration = NULL;
-
-		(*remote_proxy_factory_ptr)->proxy_instances = hashMap_create(NULL, NULL, NULL, NULL);
-
-		(*remote_proxy_factory_ptr)->handle = handle;
-
-		(*remote_proxy_factory_ptr)->create_proxy_service_ptr = create;
-		(*remote_proxy_factory_ptr)->destroy_proxy_service_ptr = destroy;
-	}
-
-	return status;
-}
-
-celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!*remote_proxy_factory_ptr) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		if ((*remote_proxy_factory_ptr)->proxy_instances) {
-			hashMap_destroy((*remote_proxy_factory_ptr)->proxy_instances, false, false);
-			(*remote_proxy_factory_ptr)->proxy_instances = NULL;
-		}
-		if ((*remote_proxy_factory_ptr)->service) {
-			free((*remote_proxy_factory_ptr)->service);
-			(*remote_proxy_factory_ptr)->service = NULL;
-		}
-		free(*remote_proxy_factory_ptr);
-		*remote_proxy_factory_ptr = NULL;
-	}
-
-	return status;
-}
-
-celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	remote_proxy_factory_ptr->remote_proxy_factory_service_ptr = calloc(1, sizeof(*remote_proxy_factory_ptr->remote_proxy_factory_service_ptr));
-	if (!remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
-		status = CELIX_ENOMEM;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->factory = remote_proxy_factory_ptr;
-		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->registerProxyService = remoteProxyFactory_registerProxyService;
-		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->unregisterProxyService = remoteProxyFactory_unregisterProxyService;
-
-		remote_proxy_factory_ptr->properties = properties_create();
-		if (!remote_proxy_factory_ptr->properties) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		} else {
-			properties_set(remote_proxy_factory_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, OSGI_RSA_REMOTE_PROXY_FACTORY,
-				remote_proxy_factory_ptr->remote_proxy_factory_service_ptr, remote_proxy_factory_ptr->properties, &remote_proxy_factory_ptr->registration);
-	}
-
-	return status;
-}
-
-celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!remote_proxy_factory_ptr) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	// #TODO Remove proxy registrations
-	if (status == CELIX_SUCCESS) {
-
-		hash_map_iterator_pt iter = hashMapIterator_create(remote_proxy_factory_ptr->proxy_instances);
-		while(hashMapIterator_hasNext(iter)){
-			proxy_instance_pt proxy_instance_ptr = (proxy_instance_pt)hashMapIterator_nextValue(iter);
-
-			if (proxy_instance_ptr->service) {
-				remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
-			}
-			free(proxy_instance_ptr);
-		}
-		hashMapIterator_destroy(iter);
-
-		if (remote_proxy_factory_ptr->registration) {
-			status = serviceRegistration_unregister(remote_proxy_factory_ptr->registration);
-			remote_proxy_factory_ptr->properties = NULL;
-		}
-		if (remote_proxy_factory_ptr->properties) {
-			properties_destroy(remote_proxy_factory_ptr->properties);
-		}
-		if (remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
-			free(remote_proxy_factory_ptr->remote_proxy_factory_service_ptr);
-		}
-	}
-
-	return status;
-}
-
-
-static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback) {
-	celix_status_t status = CELIX_SUCCESS;
-	proxy_instance_pt proxy_instance_ptr = NULL;
-
-	if (!remote_proxy_factory_ptr || !remote_proxy_factory_ptr->create_proxy_service_ptr) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		proxy_instance_ptr = calloc(1, sizeof(*proxy_instance_ptr));
-		if (!proxy_instance_ptr) {
-			status = CELIX_ENOMEM;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		proxy_instance_ptr->properties = properties_create();
-		if (!proxy_instance_ptr->properties) {
-			status = CELIX_ENOMEM;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = remote_proxy_factory_ptr->create_proxy_service_ptr(remote_proxy_factory_ptr->handle, endpointDescription, rsa, sendToCallback, proxy_instance_ptr->properties, &proxy_instance_ptr->service);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		properties_set(proxy_instance_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
-
-		hash_map_iterator_pt iter = hashMapIterator_create(endpointDescription->properties);
-		while (hashMapIterator_hasNext(iter)) {
-			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-			char *key = hashMapEntry_getKey(entry);
-			char *value = hashMapEntry_getValue(entry);
-
-			properties_set(proxy_instance_ptr->properties, key, value);
-		}
-		hashMapIterator_destroy(iter);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, remote_proxy_factory_ptr->service, proxy_instance_ptr->service, proxy_instance_ptr->properties, &proxy_instance_ptr->registration_ptr);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		hashMap_put(remote_proxy_factory_ptr->proxy_instances, endpointDescription, proxy_instance_ptr);
-	}
-
-	if(status!=CELIX_SUCCESS){
-		if(proxy_instance_ptr != NULL){
-			if(proxy_instance_ptr->properties != NULL){
-				properties_destroy(proxy_instance_ptr->properties);
-			}
-			free(proxy_instance_ptr);
-		}
-	}
-
-	return status;
-}
-
-static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription) {
-	celix_status_t status = CELIX_SUCCESS;
-	proxy_instance_pt proxy_instance_ptr = NULL;
-
-	if (!remote_proxy_factory_ptr || !endpointDescription || !remote_proxy_factory_ptr->proxy_instances || !remote_proxy_factory_ptr->handle) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		proxy_instance_ptr = hashMap_remove(remote_proxy_factory_ptr->proxy_instances, endpointDescription);
-		if (proxy_instance_ptr == NULL) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		if (proxy_instance_ptr->registration_ptr) {
-			status = serviceRegistration_unregister(proxy_instance_ptr->registration_ptr);
-			proxy_instance_ptr->properties = NULL;
-		}
-		if (proxy_instance_ptr->service) {
-			status = remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
-		}
-		if (proxy_instance_ptr->properties) {
-			properties_destroy(proxy_instance_ptr->properties);
-		}
-        free(proxy_instance_ptr);
-	}
-
-	return status;
-}
-
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/endpoint_description.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/endpoint_description.h b/remote_services/remote_service_admin/public/include/endpoint_description.h
deleted file mode 100644
index de27d2e..0000000
--- a/remote_services/remote_service_admin/public/include/endpoint_description.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_description.h
- *
- *  \date       25 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DESCRIPTION_H_
-#define ENDPOINT_DESCRIPTION_H_
-
-#include "properties.h"
-#include "array_list.h"
-
-struct endpoint_description {
-    char *frameworkUUID;
-    char *id;
-    // array_list_pt intents;
-    char *service;
-    // HASH_MAP packageVersions;
-    properties_pt properties;
-    unsigned long serviceId;
-};
-
-typedef struct endpoint_description endpoint_description_t;
-typedef endpoint_description_t* endpoint_description_pt;
-
-celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription);
-celix_status_t endpointDescription_destroy(endpoint_description_pt description);
-
-
-#endif /* ENDPOINT_DESCRIPTION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/endpoint_listener.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/endpoint_listener.h b/remote_services/remote_service_admin/public/include/endpoint_listener.h
deleted file mode 100644
index 2e6359f..0000000
--- a/remote_services/remote_service_admin/public/include/endpoint_listener.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_listener.h
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_LISTENER_H_
-#define ENDPOINT_LISTENER_H_
-
-#include "array_list.h"
-#include "properties.h"
-
-#include "endpoint_description.h"
-
-static const char * const OSGI_ENDPOINT_LISTENER_SERVICE = "endpoint_listener";
-
-static const char * const OSGI_ENDPOINT_LISTENER_SCOPE = "endpoint.listener.scope";
-
-struct endpoint_listener {
-	void *handle;
-	celix_status_t (*endpointAdded)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
-	celix_status_t (*endpointRemoved)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
-};
-
-typedef struct endpoint_listener endpoint_listener_t;
-typedef endpoint_listener_t *endpoint_listener_pt;
-
-
-#endif /* ENDPOINT_LISTENER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/export_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/export_registration.h b/remote_services/remote_service_admin/public/include/export_registration.h
deleted file mode 100644
index dc3882b..0000000
--- a/remote_services/remote_service_admin/public/include/export_registration.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef CELIX_EXPORT_REGISTRATION_H
-#define CELIX_EXPORT_REGISTRATION_H
-
-#include "celix_errno.h"
-#include "endpoint_description.h"
-#include "service_reference.h"
-
-typedef struct export_registration *export_registration_pt;
-
-typedef struct export_reference *export_reference_pt;
-
-celix_status_t exportRegistration_close(export_registration_pt registration);
-celix_status_t exportRegistration_getException(export_registration_pt registration);
-celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference);
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
-celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service);
-
-#endif //CELIX_EXPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/import_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/import_registration.h b/remote_services/remote_service_admin/public/include/import_registration.h
deleted file mode 100644
index ef8193f..0000000
--- a/remote_services/remote_service_admin/public/include/import_registration.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef CELIX_IMPORT_REGISTRATION_H
-#define CELIX_IMPORT_REGISTRATION_H
-
-#include "celix_errno.h"
-#include "endpoint_description.h"
-#include "service_reference.h"
-
-typedef struct import_registration *import_registration_pt;
-
-typedef struct import_reference *import_reference_pt;
-
-celix_status_t importRegistration_close(import_registration_pt registration);
-celix_status_t importRegistration_getException(import_registration_pt registration);
-celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference);
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
-celix_status_t importReference_getImportedService(import_reference_pt reference);
-
-#endif //CELIX_IMPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/remote_constants.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_constants.h b/remote_services/remote_service_admin/public/include/remote_constants.h
deleted file mode 100644
index 0736685..0000000
--- a/remote_services/remote_service_admin/public/include/remote_constants.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_constants.h
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_CONSTANTS_H_
-#define REMOTE_CONSTANTS_H_
-
-static const char * const OSGI_RSA_SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
-static const char * const OSGI_RSA_ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
-static const char * const OSGI_RSA_ENDPOINT_SERVICE_ID = "endpoint.service.id";
-static const char * const OSGI_RSA_ENDPOINT_ID = "endpoint.id";
-static const char * const OSGI_RSA_SERVICE_IMPORTED = "service.imported";
-static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
-static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location";
-
-#endif /* REMOTE_CONSTANTS_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/remote_endpoint.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_endpoint.h b/remote_services/remote_service_admin/public/include/remote_endpoint.h
deleted file mode 100644
index ab80abb..0000000
--- a/remote_services/remote_service_admin/public/include/remote_endpoint.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_endpoint.h
- *
- *  \date       Oct 7, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_ENDPOINT_H_
-#define REMOTE_ENDPOINT_H_
-
-#define OSGI_RSA_REMOTE_ENDPOINT "remote_endpoint"
-
-typedef struct remote_endpoint remote_endpoint_t;
-typedef remote_endpoint_t* remote_endpoint_pt;
-
-struct remote_endpoint_service {
-	remote_endpoint_pt endpoint;
-	celix_status_t (*setService)(remote_endpoint_pt endpoint, void *service);
-	celix_status_t (*handleRequest)(remote_endpoint_pt endpoint, char *data, char **reply);
-};
-
-typedef struct remote_endpoint_service *remote_endpoint_service_pt;
-
-
-#endif /* REMOTE_ENDPOINT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/remote_endpoint_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_endpoint_impl.h b/remote_services/remote_service_admin/public/include/remote_endpoint_impl.h
deleted file mode 100644
index 3782d62..0000000
--- a/remote_services/remote_service_admin/public/include/remote_endpoint_impl.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_endpoint_impl.h
- *
- *  \date       Oct 11, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_ENDPOINT_IMPL_H_
-#define REMOTE_ENDPOINT_IMPL_H_
-
-#include "remote_endpoint.h"
-#include "celix_threads.h"
-
-struct remote_endpoint {
-	celix_thread_mutex_t serviceLock;
-	void *service;
-};
-
-#endif /* REMOTE_ENDPOINT_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/remote_proxy.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_proxy.h b/remote_services/remote_service_admin/public/include/remote_proxy.h
deleted file mode 100644
index 4c3f5c3..0000000
--- a/remote_services/remote_service_admin/public/include/remote_proxy.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_proxy.h
- *
- *  \date       Oct 13, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_PROXY_H_
-#define REMOTE_PROXY_H_
-
-#include "endpoint_listener.h"
-#include "remote_service_admin.h"
-
-#define OSGI_RSA_REMOTE_PROXY_FACTORY 	"remote_proxy_factory"
-#define OSGI_RSA_REMOTE_PROXY_TIMEOUT   "remote_proxy_timeout"
-
-typedef celix_status_t (*sendToHandle)(remote_service_admin_pt remote_service_admin_ptr, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
-typedef celix_status_t (*createProxyService)(void *handle, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback, properties_pt properties, void **service);
-typedef celix_status_t (*destroyProxyService)(void *handle, void *service);
-
-typedef struct remote_proxy_factory *remote_proxy_factory_pt;
-typedef struct remote_proxy_factory_service *remote_proxy_factory_service_pt;
-
-struct remote_proxy_factory {
-	bundle_context_pt context_ptr;
-	char *service;
-
-	remote_proxy_factory_service_pt remote_proxy_factory_service_ptr;
-	properties_pt properties;
-	service_registration_pt registration;
-
-	hash_map_pt proxy_instances;
-
-	void *handle;
-
-	createProxyService create_proxy_service_ptr;
-	destroyProxyService destroy_proxy_service_ptr;
-};
-
-struct remote_proxy_factory_service {
-	remote_proxy_factory_pt factory;
-	celix_status_t (*registerProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint, remote_service_admin_pt remote_service_admin_ptr, sendToHandle callback);
-	celix_status_t (*unregisterProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint);
-};
-
-celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
-		createProxyService create, destroyProxyService destroy,
-		remote_proxy_factory_pt *remote_proxy_factory_ptr);
-celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr);
-
-celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr);
-celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr);
-
-
-
-
-#endif /* REMOTE_PROXY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/remote_service_admin.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_service_admin.h b/remote_services/remote_service_admin/public/include/remote_service_admin.h
deleted file mode 100644
index cc7fd98..0000000
--- a/remote_services/remote_service_admin/public/include/remote_service_admin.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin.h
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_H_
-#define REMOTE_SERVICE_ADMIN_H_
-
-#include "endpoint_listener.h"
-#include "service_reference.h"
-#include "export_registration.h"
-#include "import_registration.h"
-
-#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
-
-typedef struct import_registration_factory import_registration_factory_t;
-typedef import_registration_factory_t* import_registration_factory_pt;
-
-typedef struct remote_service_admin remote_service_admin_t;
-typedef remote_service_admin_t* remote_service_admin_pt;
-
-struct remote_service_admin_service {
-	remote_service_admin_pt admin;
-	celix_status_t (*exportService)(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
-	celix_status_t (*removeExportedService)(remote_service_admin_pt admin, export_registration_pt registration);
-	celix_status_t (*getExportedServices)(remote_service_admin_pt admin, array_list_pt *services);
-	celix_status_t (*getImportedEndpoints)(remote_service_admin_pt admin, array_list_pt *services);
-	celix_status_t (*importService)(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
-
-	celix_status_t (*exportReference_getExportedEndpoint)(export_reference_pt reference, endpoint_description_pt *endpoint);
-	celix_status_t (*exportReference_getExportedService)(export_reference_pt reference, service_reference_pt *service);
-
-	celix_status_t (*exportRegistration_close)(remote_service_admin_pt admin, export_registration_pt registration);
-	celix_status_t (*exportRegistration_getException)(export_registration_pt registration);
-	celix_status_t (*exportRegistration_getExportReference)(export_registration_pt registration, export_reference_pt *reference);
-	celix_status_t (*exportRegistration_freeExportReference)(export_reference_pt *reference);
-	celix_status_t (*exportRegistration_getEndpointDescription)(export_registration_pt registration, endpoint_description_pt endpointDescription);
-
-	celix_status_t (*importReference_getImportedEndpoint)(import_reference_pt reference);
-	celix_status_t (*importReference_getImportedService)(import_reference_pt reference);
-
-	celix_status_t (*importRegistration_close)(remote_service_admin_pt admin, import_registration_pt registration);
-	celix_status_t (*importRegistration_getException)(import_registration_pt registration);
-	celix_status_t (*importRegistration_getImportReference)(import_registration_pt registration, import_reference_pt *reference);
-
-};
-
-typedef struct remote_service_admin_service remote_service_admin_service_t;
-typedef remote_service_admin_service_t* remote_service_admin_service_pt;
-
-
-#endif /* REMOTE_SERVICE_ADMIN_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/CMakeLists.txt b/remote_services/remote_service_admin_api/CMakeLists.txt
new file mode 100644
index 0000000..a7d0640
--- /dev/null
+++ b/remote_services/remote_service_admin_api/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+add_library(remote_service_admin_api INTERFACE)
+target_include_directories(remote_service_admin_api INTERFACE include)
+
+install (FILES 
+        include/remote_endpoint_impl.h
+        include/remote_endpoint.h
+        include/remote_proxy.h
+        include/remote_service_admin.h
+        include/export_registration.h
+        include/import_registration.h
+        include/endpoint_description.h
+        include/endpoint_listener.h
+        include/remote_constants.h
+    DESTINATION 
+        include/celix/remote_service_admin 
+    COMPONENT 
+        remote_service_admin
+)
+install (FILES 
+        public/include/endpoint_listener.h
+    DESTINATION 
+        include/celix/endpoint_listener 
+    COMPONENT 
+        remote_service_admin
+)
+
+#Setup target aliases to match external usage
+add_library(Celix::remote_service_admin_api ALIAS remote_service_admin_api)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/README.md
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/README.md b/remote_services/remote_service_admin_api/README.md
new file mode 100644
index 0000000..2e3d268
--- /dev/null
+++ b/remote_services/remote_service_admin_api/README.md
@@ -0,0 +1,11 @@
+# Remote Service Admin
+
+The Remote Service Admin (RSA) provides the mechanisms to import and export services when instructed to do so by the Topology Manager. 
+
+To delegate method calls to the actual service implementation, the RSA_SHM and the RSA_HTTP are using "endpoint/proxy" bundles, which has all the knowledge about the marshalling and unmarshalling of data for the service. The RSA_DFI implementation combines a [foreign function interface](https://en.wikipedia.org/wiki/Foreign_function_interface) technique together with manualy created descriptors.  
+
+Note that this folder contains code commonly used by the RSA implementations and therefore does not include any CMAKE configuration.
+
+## Properties
+    ENDPOINTS				 defines the relative directory where endpoints and proxys can be found (default: endpoints)
+    CELIX_FRAMEWORK_EXTENDER_PATH  Used in RSA_DFI only. Can be used to define a path to use as an extender path point for the framework bundle. For normal bundles the bundle cache is used. 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/endpoint_description.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/endpoint_description.h b/remote_services/remote_service_admin_api/include/endpoint_description.h
new file mode 100644
index 0000000..de27d2e
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/endpoint_description.h
@@ -0,0 +1,50 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_description.h
+ *
+ *  \date       25 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DESCRIPTION_H_
+#define ENDPOINT_DESCRIPTION_H_
+
+#include "properties.h"
+#include "array_list.h"
+
+struct endpoint_description {
+    char *frameworkUUID;
+    char *id;
+    // array_list_pt intents;
+    char *service;
+    // HASH_MAP packageVersions;
+    properties_pt properties;
+    unsigned long serviceId;
+};
+
+typedef struct endpoint_description endpoint_description_t;
+typedef endpoint_description_t* endpoint_description_pt;
+
+celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription);
+celix_status_t endpointDescription_destroy(endpoint_description_pt description);
+
+
+#endif /* ENDPOINT_DESCRIPTION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/endpoint_listener.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/endpoint_listener.h b/remote_services/remote_service_admin_api/include/endpoint_listener.h
new file mode 100644
index 0000000..2e6359f
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/endpoint_listener.h
@@ -0,0 +1,49 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_listener.h
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_LISTENER_H_
+#define ENDPOINT_LISTENER_H_
+
+#include "array_list.h"
+#include "properties.h"
+
+#include "endpoint_description.h"
+
+static const char * const OSGI_ENDPOINT_LISTENER_SERVICE = "endpoint_listener";
+
+static const char * const OSGI_ENDPOINT_LISTENER_SCOPE = "endpoint.listener.scope";
+
+struct endpoint_listener {
+	void *handle;
+	celix_status_t (*endpointAdded)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+	celix_status_t (*endpointRemoved)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+};
+
+typedef struct endpoint_listener endpoint_listener_t;
+typedef endpoint_listener_t *endpoint_listener_pt;
+
+
+#endif /* ENDPOINT_LISTENER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/export_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/export_registration.h b/remote_services/remote_service_admin_api/include/export_registration.h
new file mode 100644
index 0000000..dc3882b
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/export_registration.h
@@ -0,0 +1,22 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef CELIX_EXPORT_REGISTRATION_H
+#define CELIX_EXPORT_REGISTRATION_H
+
+#include "celix_errno.h"
+#include "endpoint_description.h"
+#include "service_reference.h"
+
+typedef struct export_registration *export_registration_pt;
+
+typedef struct export_reference *export_reference_pt;
+
+celix_status_t exportRegistration_close(export_registration_pt registration);
+celix_status_t exportRegistration_getException(export_registration_pt registration);
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference);
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
+celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service);
+
+#endif //CELIX_EXPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/import_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/import_registration.h b/remote_services/remote_service_admin_api/include/import_registration.h
new file mode 100644
index 0000000..ef8193f
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/import_registration.h
@@ -0,0 +1,22 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef CELIX_IMPORT_REGISTRATION_H
+#define CELIX_IMPORT_REGISTRATION_H
+
+#include "celix_errno.h"
+#include "endpoint_description.h"
+#include "service_reference.h"
+
+typedef struct import_registration *import_registration_pt;
+
+typedef struct import_reference *import_reference_pt;
+
+celix_status_t importRegistration_close(import_registration_pt registration);
+celix_status_t importRegistration_getException(import_registration_pt registration);
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference);
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
+celix_status_t importReference_getImportedService(import_reference_pt reference);
+
+#endif //CELIX_IMPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/remote_constants.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_constants.h b/remote_services/remote_service_admin_api/include/remote_constants.h
new file mode 100644
index 0000000..0736685
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_constants.h
@@ -0,0 +1,38 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_constants.h
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_CONSTANTS_H_
+#define REMOTE_CONSTANTS_H_
+
+static const char * const OSGI_RSA_SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
+static const char * const OSGI_RSA_ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
+static const char * const OSGI_RSA_ENDPOINT_SERVICE_ID = "endpoint.service.id";
+static const char * const OSGI_RSA_ENDPOINT_ID = "endpoint.id";
+static const char * const OSGI_RSA_SERVICE_IMPORTED = "service.imported";
+static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
+static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location";
+
+#endif /* REMOTE_CONSTANTS_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/remote_endpoint.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_endpoint.h b/remote_services/remote_service_admin_api/include/remote_endpoint.h
new file mode 100644
index 0000000..ab80abb
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_endpoint.h
@@ -0,0 +1,44 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_endpoint.h
+ *
+ *  \date       Oct 7, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_ENDPOINT_H_
+#define REMOTE_ENDPOINT_H_
+
+#define OSGI_RSA_REMOTE_ENDPOINT "remote_endpoint"
+
+typedef struct remote_endpoint remote_endpoint_t;
+typedef remote_endpoint_t* remote_endpoint_pt;
+
+struct remote_endpoint_service {
+	remote_endpoint_pt endpoint;
+	celix_status_t (*setService)(remote_endpoint_pt endpoint, void *service);
+	celix_status_t (*handleRequest)(remote_endpoint_pt endpoint, char *data, char **reply);
+};
+
+typedef struct remote_endpoint_service *remote_endpoint_service_pt;
+
+
+#endif /* REMOTE_ENDPOINT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h b/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h
new file mode 100644
index 0000000..3782d62
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h
@@ -0,0 +1,38 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_endpoint_impl.h
+ *
+ *  \date       Oct 11, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_ENDPOINT_IMPL_H_
+#define REMOTE_ENDPOINT_IMPL_H_
+
+#include "remote_endpoint.h"
+#include "celix_threads.h"
+
+struct remote_endpoint {
+	celix_thread_mutex_t serviceLock;
+	void *service;
+};
+
+#endif /* REMOTE_ENDPOINT_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/remote_proxy.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_proxy.h b/remote_services/remote_service_admin_api/include/remote_proxy.h
new file mode 100644
index 0000000..4c3f5c3
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_proxy.h
@@ -0,0 +1,76 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_proxy.h
+ *
+ *  \date       Oct 13, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_PROXY_H_
+#define REMOTE_PROXY_H_
+
+#include "endpoint_listener.h"
+#include "remote_service_admin.h"
+
+#define OSGI_RSA_REMOTE_PROXY_FACTORY 	"remote_proxy_factory"
+#define OSGI_RSA_REMOTE_PROXY_TIMEOUT   "remote_proxy_timeout"
+
+typedef celix_status_t (*sendToHandle)(remote_service_admin_pt remote_service_admin_ptr, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
+typedef celix_status_t (*createProxyService)(void *handle, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback, properties_pt properties, void **service);
+typedef celix_status_t (*destroyProxyService)(void *handle, void *service);
+
+typedef struct remote_proxy_factory *remote_proxy_factory_pt;
+typedef struct remote_proxy_factory_service *remote_proxy_factory_service_pt;
+
+struct remote_proxy_factory {
+	bundle_context_pt context_ptr;
+	char *service;
+
+	remote_proxy_factory_service_pt remote_proxy_factory_service_ptr;
+	properties_pt properties;
+	service_registration_pt registration;
+
+	hash_map_pt proxy_instances;
+
+	void *handle;
+
+	createProxyService create_proxy_service_ptr;
+	destroyProxyService destroy_proxy_service_ptr;
+};
+
+struct remote_proxy_factory_service {
+	remote_proxy_factory_pt factory;
+	celix_status_t (*registerProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint, remote_service_admin_pt remote_service_admin_ptr, sendToHandle callback);
+	celix_status_t (*unregisterProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint);
+};
+
+celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
+		createProxyService create, destroyProxyService destroy,
+		remote_proxy_factory_pt *remote_proxy_factory_ptr);
+celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr);
+
+celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr);
+celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr);
+
+
+
+
+#endif /* REMOTE_PROXY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/remote_service_admin.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_service_admin.h b/remote_services/remote_service_admin_api/include/remote_service_admin.h
new file mode 100644
index 0000000..cc7fd98
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_service_admin.h
@@ -0,0 +1,73 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin.h
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_H_
+#define REMOTE_SERVICE_ADMIN_H_
+
+#include "endpoint_listener.h"
+#include "service_reference.h"
+#include "export_registration.h"
+#include "import_registration.h"
+
+#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
+
+typedef struct import_registration_factory import_registration_factory_t;
+typedef import_registration_factory_t* import_registration_factory_pt;
+
+typedef struct remote_service_admin remote_service_admin_t;
+typedef remote_service_admin_t* remote_service_admin_pt;
+
+struct remote_service_admin_service {
+	remote_service_admin_pt admin;
+	celix_status_t (*exportService)(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+	celix_status_t (*removeExportedService)(remote_service_admin_pt admin, export_registration_pt registration);
+	celix_status_t (*getExportedServices)(remote_service_admin_pt admin, array_list_pt *services);
+	celix_status_t (*getImportedEndpoints)(remote_service_admin_pt admin, array_list_pt *services);
+	celix_status_t (*importService)(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
+
+	celix_status_t (*exportReference_getExportedEndpoint)(export_reference_pt reference, endpoint_description_pt *endpoint);
+	celix_status_t (*exportReference_getExportedService)(export_reference_pt reference, service_reference_pt *service);
+
+	celix_status_t (*exportRegistration_close)(remote_service_admin_pt admin, export_registration_pt registration);
+	celix_status_t (*exportRegistration_getException)(export_registration_pt registration);
+	celix_status_t (*exportRegistration_getExportReference)(export_registration_pt registration, export_reference_pt *reference);
+	celix_status_t (*exportRegistration_freeExportReference)(export_reference_pt *reference);
+	celix_status_t (*exportRegistration_getEndpointDescription)(export_registration_pt registration, endpoint_description_pt endpointDescription);
+
+	celix_status_t (*importReference_getImportedEndpoint)(import_reference_pt reference);
+	celix_status_t (*importReference_getImportedService)(import_reference_pt reference);
+
+	celix_status_t (*importRegistration_close)(remote_service_admin_pt admin, import_registration_pt registration);
+	celix_status_t (*importRegistration_getException)(import_registration_pt registration);
+	celix_status_t (*importRegistration_getImportReference)(import_registration_pt registration, import_reference_pt *reference);
+
+};
+
+typedef struct remote_service_admin_service remote_service_admin_service_t;
+typedef remote_service_admin_service_t* remote_service_admin_service_pt;
+
+
+#endif /* REMOTE_SERVICE_ADMIN_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/CMakeLists.txt b/remote_services/remote_service_admin_common/CMakeLists.txt
new file mode 100644
index 0000000..1813211
--- /dev/null
+++ b/remote_services/remote_service_admin_common/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+add_library(remote_service_admin_common STATIC
+    src/endpoint_description.c
+    src/export_registration_impl.c
+    src/import_registration_impl.c
+)
+target_include_directories(remote_service_admin_common PRIVATE src)
+target_link_libraries(remote_service_admin_common PUBLIC Celix::framework Celix::remote_service_admin_api Celix::log_helper)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/endpoint_description.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/endpoint_description.c b/remote_services/remote_service_admin_common/src/endpoint_description.c
new file mode 100644
index 0000000..0d8b684
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/endpoint_description.c
@@ -0,0 +1,89 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_description.c
+ *
+ *  \date       25 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "celix_errno.h"
+#include "celix_log.h"
+
+#include "endpoint_description.h"
+#include "remote_constants.h"
+#include "constants.h"
+
+static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty);
+
+celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	unsigned long serviceId = 0UL;
+	status = endpointDescription_verifyLongProperty(properties, (char *) OSGI_RSA_ENDPOINT_SERVICE_ID, &serviceId);
+	if (status != CELIX_SUCCESS) {
+		return status;
+	}
+
+	endpoint_description_pt ep = calloc(1,sizeof(*ep));
+
+    ep->properties = properties;
+    ep->frameworkUUID = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+    ep->id = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_ID);
+    ep->service = strndup(properties_get(properties, OSGI_FRAMEWORK_OBJECTCLASS), 1024*10);
+    ep->serviceId = serviceId;
+
+    if (!(ep->frameworkUUID) || !(ep->id) || !(ep->service) ) {
+    	fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "ENDPOINT_DESCRIPTION: incomplete description!.");
+    	status = CELIX_BUNDLE_EXCEPTION;
+    }
+
+    if(status == CELIX_SUCCESS){
+	*endpointDescription = ep;
+    }
+    else{
+	*endpointDescription = NULL;
+	free(ep);
+    }
+
+    return status;
+}
+
+celix_status_t endpointDescription_destroy(endpoint_description_pt description) {
+    properties_destroy(description->properties);
+    free(description->service);
+    free(description);
+    return CELIX_SUCCESS;
+}
+
+static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    const char *value = properties_get(properties, propertyName);
+    if (value == NULL) {
+        *longProperty = 0UL;
+    } else {
+        *longProperty = strtoul(value,NULL,10);
+    }
+
+    return status;
+}


[19/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/2a670f26
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/2a670f26
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/2a670f26

Branch: refs/heads/feature/CELIX-417-cmake-refactor
Commit: 2a670f26579d89e5404979d7fffb4ed27040441c
Parents: a1c3088
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Nov 21 21:07:44 2017 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Nov 21 21:07:44 2017 +0100

----------------------------------------------------------------------
 cmake/cmake_celix/BundlePackaging.cmake         |    2 +-
 cmake/cmake_celix/DockerPackaging.cmake         |   17 +-
 deployment_admin/CMakeLists.txt                 |    2 +-
 examples/dm_example_cxx/CMakeLists.txt          |   16 +-
 examples/dm_example_cxx/phase1/CMakeLists.txt   |    4 +-
 examples/hello_world/CMakeLists.txt             |    8 +-
 examples/services_example_c/bar/CMakeLists.txt  |    4 +-
 log_writer/CMakeLists.txt                       |    6 +-
 log_writer/README.md                            |   10 +-
 log_writer/log_writer_stdout/CMakeLists.txt     |   10 +-
 log_writer/log_writer_syslog/CMakeLists.txt     |    4 -
 pubsub/CMakeLists.txt                           |    2 +-
 pubsub/deploy/CMakeLists.txt                    |    2 +-
 .../examples/mp_pubsub/publisher/CMakeLists.txt |    2 +-
 .../mp_pubsub/subscriber/CMakeLists.txt         |    2 +-
 pubsub/examples/pubsub/publisher/CMakeLists.txt |    2 +-
 .../examples/pubsub/publisher2/CMakeLists.txt   |    2 +-
 .../examples/pubsub/subscriber/CMakeLists.txt   |    2 +-
 pubsub/pubsub_admin_udp_mc/CMakeLists.txt       |   28 +-
 .../private/include/large_udp.h                 |   45 -
 .../private/include/pubsub_admin_impl.h         |   93 -
 .../private/include/topic_publication.h         |   57 -
 .../private/include/topic_subscription.h        |   60 -
 .../pubsub_admin_udp_mc/private/src/large_udp.c |  372 -
 .../private/src/psa_activator.c                 |  141 -
 .../private/src/pubsub_admin_impl.c             | 1039 ---
 .../private/src/topic_publication.c             |  444 -
 .../private/src/topic_subscription.c            |  635 --
 pubsub/pubsub_admin_udp_mc/src/large_udp.c      |  372 +
 pubsub/pubsub_admin_udp_mc/src/large_udp.h      |   45 +
 pubsub/pubsub_admin_udp_mc/src/psa_activator.c  |  141 +
 .../pubsub_admin_udp_mc/src/pubsub_admin_impl.c | 1039 +++
 .../pubsub_admin_udp_mc/src/pubsub_admin_impl.h |   93 +
 .../pubsub_admin_udp_mc/src/topic_publication.c |  444 +
 .../pubsub_admin_udp_mc/src/topic_publication.h |   57 +
 .../src/topic_subscription.c                    |  635 ++
 .../src/topic_subscription.h                    |   60 +
 pubsub/pubsub_admin_zmq/CMakeLists.txt          |    5 +-
 pubsub/pubsub_discovery/CMakeLists.txt          |   27 +-
 .../private/include/etcd_common.h               |   28 -
 .../private/include/etcd_watcher.h              |   38 -
 .../private/include/etcd_writer.h               |   39 -
 .../private/include/pubsub_discovery_impl.h     |   72 -
 .../pubsub_discovery/private/src/etcd_common.c  |   82 -
 .../pubsub_discovery/private/src/etcd_watcher.c |  290 -
 .../pubsub_discovery/private/src/etcd_writer.c  |  189 -
 .../private/src/psd_activator.c                 |  171 -
 .../private/src/pubsub_discovery_impl.c         |  457 -
 .../public/include/pubsub_discovery.h           |   26 -
 pubsub/pubsub_discovery/src/etcd_common.c       |   82 +
 pubsub/pubsub_discovery/src/etcd_common.h       |   28 +
 pubsub/pubsub_discovery/src/etcd_watcher.c      |  290 +
 pubsub/pubsub_discovery/src/etcd_watcher.h      |   38 +
 pubsub/pubsub_discovery/src/etcd_writer.c       |  189 +
 pubsub/pubsub_discovery/src/etcd_writer.h       |   39 +
 pubsub/pubsub_discovery/src/psd_activator.c     |  171 +
 pubsub/pubsub_discovery/src/pubsub_discovery.h  |   26 +
 .../src/pubsub_discovery_impl.c                 |  457 +
 .../src/pubsub_discovery_impl.h                 |   72 +
 pubsub/pubsub_serializer_json/CMakeLists.txt    |   20 +-
 .../private/include/pubsub_serializer_impl.h    |   55 -
 .../private/src/ps_activator.c                  |  107 -
 .../private/src/pubsub_serializer_impl.c        |  295 -
 .../pubsub_serializer_json/src/ps_activator.c   |  107 +
 .../src/pubsub_serializer_impl.c                |  295 +
 .../src/pubsub_serializer_impl.h                |   55 +
 pubsub/pubsub_topology_manager/CMakeLists.txt   |   12 +-
 pubsub/test/CMakeLists.txt                      |    6 +-
 remote_services/CMakeLists.txt                  |    6 +-
 .../discovery/private/include/discovery.h       |   67 -
 .../include/endpoint_descriptor_common.h        |   61 -
 .../include/endpoint_descriptor_reader.h        |   42 -
 .../include/endpoint_descriptor_writer.h        |   39 -
 .../private/include/endpoint_discovery_poller.h |   56 -
 .../private/include/endpoint_discovery_server.h |   81 -
 remote_services/discovery/private/src/desc.xml  |   41 -
 .../discovery/private/src/discovery.c           |  233 -
 .../discovery/private/src/discovery_activator.c |  186 -
 .../private/src/endpoint_descriptor_reader.c    |  387 -
 .../private/src/endpoint_descriptor_writer.c    |  233 -
 .../private/src/endpoint_discovery_poller.c     |  403 -
 .../private/src/endpoint_discovery_server.c     |  450 -
 remote_services/discovery_common/CMakeLists.txt |   33 +
 .../discovery_common/include/civetweb.h         |  657 ++
 .../discovery_common/include/discovery.h        |   67 +
 .../include/endpoint_descriptor_common.h        |   61 +
 .../include/endpoint_descriptor_reader.h        |   42 +
 .../include/endpoint_descriptor_writer.h        |   39 +
 .../include/endpoint_discovery_poller.h         |   56 +
 .../include/endpoint_discovery_server.h         |   81 +
 remote_services/discovery_common/src/civetweb.c | 7907 ++++++++++++++++++
 remote_services/discovery_common/src/desc.xml   |   41 +
 .../discovery_common/src/discovery.c            |  234 +
 .../discovery_common/src/discovery_activator.c  |  186 +
 .../src/endpoint_descriptor_reader.c            |  387 +
 .../src/endpoint_descriptor_writer.c            |  233 +
 .../src/endpoint_discovery_poller.c             |  403 +
 .../src/endpoint_discovery_server.c             |  450 +
 remote_services/discovery_common/src/md5.inl    |  461 +
 .../discovery_configured/CMakeLists.txt         |   36 +-
 .../private/include/discovery_impl.h            |   62 -
 .../discovery_configured/private/src/desc.xml   |   41 -
 .../private/src/discovery_impl.c                |  123 -
 .../discovery_configured/src/desc.xml           |   41 +
 .../discovery_configured/src/discovery_impl.c   |  123 +
 .../discovery_configured/src/discovery_impl.h   |   62 +
 remote_services/discovery_etcd/CMakeLists.txt   |   33 +-
 remote_services/discovery_shm/CMakeLists.txt    |   35 +-
 .../private/include/discovery_impl.h            |   66 -
 .../private/include/discovery_shm.h             |   56 -
 .../private/include/discovery_shmWatcher.h      |   40 -
 .../discovery_shm/private/src/discovery_impl.c  |  163 -
 .../discovery_shm/private/src/discovery_shm.c   |  284 -
 .../private/src/discovery_shmWatcher.c          |  246 -
 .../discovery_shm/src/discovery_impl.c          |  163 +
 .../discovery_shm/src/discovery_impl.h          |   66 +
 .../discovery_shm/src/discovery_shm.c           |  284 +
 .../discovery_shm/src/discovery_shm.h           |   56 +
 .../discovery_shm/src/discovery_shmWatcher.c    |  246 +
 .../discovery_shm/src/discovery_shmWatcher.h    |   40 +
 remote_services/examples/CMakeLists.txt         |    5 +-
 .../examples/calculator_api/CMakeLists.txt      |   22 +
 .../calculator_api/include/calculator_service.h |   56 +
 ...apache.celix.calc.api.Calculator2.descriptor |   11 +
 .../examples/calculator_service/CMakeLists.txt  |   22 +-
 .../private/include/calculator_impl.h           |   43 -
 .../private/src/calculator_activator.c          |  110 -
 .../private/src/calculator_impl.c               |   79 -
 .../public/include/calculator_service.h         |   56 -
 ...apache.celix.calc.api.Calculator2.descriptor |   11 -
 .../src/calculator_activator.c                  |  110 +
 .../calculator_service/src/calculator_impl.c    |   79 +
 .../calculator_service/src/calculator_impl.h    |   43 +
 .../examples/calculator_shell/CMakeLists.txt    |   28 +-
 .../private/include/add_command.h               |   32 -
 ...apache.celix.calc.api.Calculator2.descriptor |   11 -
 .../private/include/sqrt_command.h              |   32 -
 .../private/include/sub_command.h               |   32 -
 .../calculator_shell/private/src/add_command.c  |  101 -
 .../private/src/calculator_shell_activator.c    |  125 -
 .../calculator_shell/private/src/sqrt_command.c |   96 -
 .../calculator_shell/private/src/sub_command.c  |   99 -
 .../examples/calculator_shell/src/add_command.c |  101 +
 .../examples/calculator_shell/src/add_command.h |   32 +
 .../src/calculator_shell_activator.c            |  125 +
 ...apache.celix.calc.api.Calculator2.descriptor |   11 +
 .../calculator_shell/src/sqrt_command.c         |   96 +
 .../calculator_shell/src/sqrt_command.h         |   32 +
 .../examples/calculator_shell/src/sub_command.c |   99 +
 .../examples/calculator_shell/src/sub_command.h |   32 +
 .../remote_service_admin/CMakeLists.txt         |   46 -
 remote_services/remote_service_admin/README.md  |   11 -
 .../private/include/export_registration_impl.h  |   61 -
 .../private/include/import_registration_impl.h  |   81 -
 .../private/include/remote_service_admin_impl.h |   49 -
 .../private/src/endpoint_description.c          |   89 -
 .../private/src/export_registration_impl.c      |  257 -
 .../private/src/import_registration_impl.c      |  274 -
 .../private/src/remote_proxy_factory_impl.c     |  252 -
 .../public/include/endpoint_description.h       |   50 -
 .../public/include/endpoint_listener.h          |   49 -
 .../public/include/export_registration.h        |   22 -
 .../public/include/import_registration.h        |   22 -
 .../public/include/remote_constants.h           |   38 -
 .../public/include/remote_endpoint.h            |   44 -
 .../public/include/remote_endpoint_impl.h       |   38 -
 .../public/include/remote_proxy.h               |   76 -
 .../public/include/remote_service_admin.h       |   73 -
 .../remote_service_admin_api/CMakeLists.txt     |   45 +
 .../remote_service_admin_api/README.md          |   11 +
 .../include/endpoint_description.h              |   50 +
 .../include/endpoint_listener.h                 |   49 +
 .../include/export_registration.h               |   22 +
 .../include/import_registration.h               |   22 +
 .../include/remote_constants.h                  |   38 +
 .../include/remote_endpoint.h                   |   44 +
 .../include/remote_endpoint_impl.h              |   38 +
 .../include/remote_proxy.h                      |   76 +
 .../include/remote_service_admin.h              |   73 +
 .../remote_service_admin_common/CMakeLists.txt  |   24 +
 .../src/endpoint_description.c                  |   89 +
 .../src/export_registration_impl.c              |  257 +
 .../src/export_registration_impl.h              |   61 +
 .../src/import_registration_impl.c              |  274 +
 .../src/import_registration_impl.h              |   81 +
 .../src/remote_proxy_factory_impl.c             |  252 +
 .../src/remote_service_admin_impl.h             |   49 +
 .../remote_service_admin_dfi/rsa/CMakeLists.txt |   31 +-
 .../rsa/private/include/dfi_utils.h             |   30 -
 .../private/include/export_registration_dfi.h   |   38 -
 .../private/include/import_registration_dfi.h   |   44 -
 .../private/include/remote_service_admin_dfi.h  |   57 -
 .../rsa/private/src/dfi_utils.c                 |   98 -
 .../rsa/private/src/export_registration_dfi.c   |  251 -
 .../rsa/private/src/import_registration_dfi.c   |  402 -
 .../src/remote_service_admin_activator.c        |  124 -
 .../rsa/private/src/remote_service_admin_dfi.c  |  775 --
 .../rsa/src/dfi_utils.c                         |   98 +
 .../rsa/src/dfi_utils.h                         |   30 +
 .../rsa/src/export_registration_dfi.c           |  251 +
 .../rsa/src/export_registration_dfi.h           |   38 +
 .../rsa/src/import_registration_dfi.c           |  402 +
 .../rsa/src/import_registration_dfi.h           |   44 +
 .../rsa/src/remote_service_admin_activator.c    |  124 +
 .../rsa/src/remote_service_admin_dfi.c          |  775 ++
 .../rsa/src/remote_service_admin_dfi.h          |   57 +
 .../rsa_tst/CMakeLists.txt                      |    4 +-
 .../rsa_tst/bundle/CMakeLists.txt               |   14 +-
 remote_services/topology_manager/CMakeLists.txt |   26 +-
 .../topology_manager/include/tm_scope.h         |   46 +
 .../topology_manager/private/include/scope.h    |  150 -
 .../private/include/topology_manager.h          |   65 -
 .../topology_manager/private/src/activator.c    |  289 -
 .../topology_manager/private/src/scope.c        |  326 -
 .../private/src/topology_manager.c              |  985 ---
 .../topology_manager/public/include/tm_scope.h  |   46 -
 .../topology_manager/src/activator.c            |  289 +
 remote_services/topology_manager/src/scope.c    |  326 +
 remote_services/topology_manager/src/scope.h    |  150 +
 .../topology_manager/src/topology_manager.c     |  985 +++
 .../topology_manager/src/topology_manager.h     |   65 +
 .../topology_manager/tms_tst/CMakeLists.txt     |    4 +-
 .../tms_tst/bundle/CMakeLists.txt               |    2 +-
 .../tms_tst/disc_mock/CMakeLists.txt            |   11 +-
 .../utils/private/include/civetweb.h            |  657 --
 remote_services/utils/private/src/civetweb.c    | 7907 ------------------
 remote_services/utils/private/src/md5.inl       |  461 -
 shell/CMakeLists.txt                            |    2 +-
 shell/README.md                                 |    3 +-
 229 files changed, 23404 insertions(+), 23450 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/cmake/cmake_celix/BundlePackaging.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/BundlePackaging.cmake b/cmake/cmake_celix/BundlePackaging.cmake
index 2071fca..c5d75d6 100644
--- a/cmake/cmake_celix/BundlePackaging.cmake
+++ b/cmake/cmake_celix/BundlePackaging.cmake
@@ -371,7 +371,7 @@ function(bundle_import_libs)
             list(APPEND LIBS "$<TARGET_SONAME_FILE_NAME:${LIB}>")
         endif()
 
-        target_link_libraries(${BUNDLE} ${LIB})
+        target_link_libraries(${BUNDLE} PRIVATE ${LIB})
     endforeach()
 
 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/cmake/cmake_celix/DockerPackaging.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/DockerPackaging.cmake b/cmake/cmake_celix/DockerPackaging.cmake
index 7cce6dd..b85da11 100644
--- a/cmake/cmake_celix/DockerPackaging.cmake
+++ b/cmake/cmake_celix/DockerPackaging.cmake
@@ -116,22 +116,16 @@ function(add_celix_docker)
         DEPENDS ${TIMESTAMP_FILE}
     )
 
-    #Setting CELIX_LIB_DIRS, CELIX_BIN_DIR and CELIX_LAUNCHER 
-    if (EXISTS ${CELIX_FRAMEWORK_LIBRARY}) 
-        #CELIX_FRAMEWORK_LIBRARY set by FindCelix.cmake -> Celix Based Project
-        #CELIX_LAUNCHER is set by FindCelix.cmake
-    else()
-        set(CELIX_LAUNCHER "$<TARGET_FILE:celix>")
-    endif()
+    set(CELIX_LAUNCHER "$<TARGET_FILE:Celix::launcher>")
 
     #setup dependencies based on timestamp
     if (DOCKER_CREATE_FS)
         add_custom_command(OUTPUT "${TIMESTAMP_FILE}"
             COMMAND ${CMAKE_COMMAND} -E touch ${TIMESTAMP_FILE}
-	    COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC>
-	    COMMAND cd $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC> && /bin/bash ${CELIX_CMAKE_DIRECTORY}/cmake_celix/create_target_filesystem.sh -e ${CELIX_LAUNCHER} -l $<TARGET_FILE:${DOCKER_DEPSLIB}> > /dev/null
+            COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC>
+            COMMAND cd $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC> && /bin/bash ${CELIX_CMAKE_DIRECTORY}/cmake_celix/create_target_filesystem.sh -e ${CELIX_LAUNCHER} -l $<TARGET_FILE:${DOCKER_DEPSLIB}> > /dev/null
             DEPENDS  "$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_DEPS>" ${DOCKERFILE} ${DOCKER_DEPSLIB}
-	    WORKING_DIRECTORY "${DOCKER_LOC}"
+            WORKING_DIRECTORY "${DOCKER_LOC}"
             COMMENT "Creating docker dir for ${DOCKER_TARGET}" VERBATIM
         )
     else ()
@@ -248,7 +242,8 @@ function(celix_docker_bundles)
                     COMMENT "Copying bundle '${BUNDLE}' to '${OUT}'"
                     DEPENDS ${BUNDLE}
             )
-            add_dependencies(${DOCKER_TARGET} ${BUNDLE}_bundle) #ensure the the deploy depends on the _bundle target, custom_command depends on add_library
+            get_target_property(BUILD_BUNDLE_TARGET ${BUNDLE} BUNDLE_BUILD_BUNDLE_TARGET)
+            add_dependencies(${DOCKER_TARGET} ${BUILD_BUNDLE_TARGET}) #ensure the the deploy depends on the _bundle target, custom_command depends on add_library
         endif()
         list(APPEND DEPS "${OUT}")
     endforeach()

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/deployment_admin/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/deployment_admin/CMakeLists.txt b/deployment_admin/CMakeLists.txt
index 4a06be5..3eb38ec 100644
--- a/deployment_admin/CMakeLists.txt
+++ b/deployment_admin/CMakeLists.txt
@@ -57,7 +57,7 @@ if (DEPLOYMENT_ADMIN)
     add_library(Celix::deployment_admin ALIAS deployment_admin)
 
     add_deploy(deployment-admin
-        BUNDLES Celix::deployment_admin Celix::shell Celix::shell_tui log_service log_writer
+        BUNDLES Celix::deployment_admin Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout
         PROPERTIES
     		"deployment_admin_url=http://localhost:8080"
     		"deployment_admin_identification=celix"

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/examples/dm_example_cxx/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/CMakeLists.txt b/examples/dm_example_cxx/CMakeLists.txt
index 1a47113..012f706 100644
--- a/examples/dm_example_cxx/CMakeLists.txt
+++ b/examples/dm_example_cxx/CMakeLists.txt
@@ -36,9 +36,9 @@ if (BUILD_DEPENDENCY_MANAGER_CXX)
         BUNDLES
             Celix::shell
             Celix::shell_tui
-            dm_shell
-            log_service
-            log_writer
+            Celix::dm_shell
+            Celix::log_service
+            Celix::log_writer_stdout
 
             phase1_cxx
             phase2a_cxx
@@ -55,11 +55,11 @@ if (BUILD_DEPENDENCY_MANAGER_CXX)
             BUNDLES_DIR /usr/share/bundles
             WORKDIR /workspace
             BUNDLES
-                celix_shell
-                shell_tui
-                dm_shell
-                log_service
-                log_writer
+                Celix::shell
+                Celix::shell_tui
+                Celix::dm_shell
+                Celix::log_service
+                Celix::log_writer_stdout
 
                 phase1_cxx
                 phase2a_cxx

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/examples/dm_example_cxx/phase1/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase1/CMakeLists.txt b/examples/dm_example_cxx/phase1/CMakeLists.txt
index 728278b..62b1658 100644
--- a/examples/dm_example_cxx/phase1/CMakeLists.txt
+++ b/examples/dm_example_cxx/phase1/CMakeLists.txt
@@ -35,8 +35,8 @@ IF(APPLE)
 else()
     if(ENABLE_ADDRESS_SANITIZER)
         #With asan there can be undefined symbols
-        target_link_libraries(phase1_cxx -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive Celix::shell_api)
+        target_link_libraries(phase1_cxx PRIVATE -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive Celix::shell_api)
     else()
-        target_link_libraries(phase1_cxx -Wl,--no-undefined -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive Celix::shell_api)
+        target_link_libraries(phase1_cxx PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive Celix::shell_api)
     endif()
 endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/examples/hello_world/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/hello_world/CMakeLists.txt b/examples/hello_world/CMakeLists.txt
index 7cb590f..ca72eec 100644
--- a/examples/hello_world/CMakeLists.txt
+++ b/examples/hello_world/CMakeLists.txt
@@ -32,7 +32,7 @@ add_library(hello_test2lib SHARED
 )
 set_library_version(hello_test2lib "3.3.3")
 
-add_bundle(hello
+add_bundle(hello_bundle
     VERSION "1.2"
     SOURCES
         private/src/activator.c
@@ -45,19 +45,19 @@ add_bundle(hello_export
     EXPORT_LIBRARIES hello_test2lib
 )
 
-bundle_private_libs(hello
+bundle_private_libs(hello_bundle
     hello_testlib
 )
 
 add_deploy(helloworld_byref
     GROUP hello
-    BUNDLES hello_export hello ${CELIX_SHELL_BUNDLE} ${CELIX_SHELL_TUI_BUNDLE}
+    BUNDLES hello_export hello_bundle ${CELIX_SHELL_BUNDLE} ${CELIX_SHELL_TUI_BUNDLE}
 )
 
 add_deploy(helloworld_withcopy
     GROUP hello
     COPY #Ensures that bundles are copied in the deploy location
-    BUNDLES hello_export hello ${SHELL_BUNDLE} ${SHELL_TUI_BUNDLE}
+    BUNDLES hello_export hello_bundle ${SHELL_BUNDLE} ${SHELL_TUI_BUNDLE}
 )
 
 endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/examples/services_example_c/bar/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/services_example_c/bar/CMakeLists.txt b/examples/services_example_c/bar/CMakeLists.txt
index 2332931..0633c06 100644
--- a/examples/services_example_c/bar/CMakeLists.txt
+++ b/examples/services_example_c/bar/CMakeLists.txt
@@ -32,8 +32,8 @@ IF(APPLE)
 else()
     if(ENABLE_ADDRESS_SANITIZER)
         #With asan there can be undefined symbols
-        target_link_libraries(bar -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
+        target_link_libraries(bar PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
     else()
-        target_link_libraries(bar -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
+        target_link_libraries(bar PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
     endif()
 endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/log_writer/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/log_writer/CMakeLists.txt b/log_writer/CMakeLists.txt
index a742af2..340af15 100644
--- a/log_writer/CMakeLists.txt
+++ b/log_writer/CMakeLists.txt
@@ -19,5 +19,9 @@ celix_subproject(LOG_WRITER "Option to enable building the Log Writer bundles" O
 if (LOG_WRITER)
     add_subdirectory(log_writer)
     add_subdirectory(log_writer_stdout)
-  	add_subdirectory(log_writer_syslog) 
+  	add_subdirectory(log_writer_syslog)
+
+    #Setup target aliases to match external usage
+    add_library(Celix::log_writer_stdout ALIAS log_writer_stdout)
+    add_library(Celix::log_writer_syslog ALIAS log_writer_syslog)
 endif (LOG_WRITER)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/log_writer/README.md
----------------------------------------------------------------------
diff --git a/log_writer/README.md b/log_writer/README.md
index 6de181d..29aebcc 100644
--- a/log_writer/README.md
+++ b/log_writer/README.md
@@ -1,7 +1,13 @@
-## Log Writer
+# Log Writer
 
 The Celix Log Writers are components that read/listen to the Log Service and print the Log entries to the console or syslog, respectively.
 
-###### CMake options
+## CMake options
     BUILD_LOG_WRITER=ON
     BUILD_LOG_WRITER_SYSLOG=ON
+
+## Using info
+
+If the Celix Log Writers is installed The `FindCelix.cmake` will set:
+ - The `Celix::log_writer_stdout` bundle target
+ - The `Celix::log_writer_syslog` bundle target

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/log_writer/log_writer_stdout/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/log_writer/log_writer_stdout/CMakeLists.txt b/log_writer/log_writer_stdout/CMakeLists.txt
index 11734cc..6070b2e 100644
--- a/log_writer/log_writer_stdout/CMakeLists.txt
+++ b/log_writer/log_writer_stdout/CMakeLists.txt
@@ -15,18 +15,14 @@
 # specific language governing permissions and limitations
 # under the License.
 
-add_bundle(log_writer
+add_bundle(log_writer_stdout
 	SYMBOLIC_NAME "apache_celix_log_writer"
 	VERSION "1.1.0"
 	NAME "Apache Celix Log Writer"
 	SOURCES
-		#${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/src/log_writer_activator
-		#${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/src/log_writer
-		#${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/include/log_writer.h
-
 		src/log_writer_stdout
 )
 
-install_bundle(log_writer)
+install_bundle(log_writer_stdout)
 
-target_link_libraries(log_writer PRIVATE Celix::log_service_api log_writer_common)
\ No newline at end of file
+target_link_libraries(log_writer_stdout PRIVATE Celix::log_service_api log_writer_common)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/log_writer/log_writer_syslog/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/log_writer/log_writer_syslog/CMakeLists.txt b/log_writer/log_writer_syslog/CMakeLists.txt
index caad713..b98b914 100644
--- a/log_writer/log_writer_syslog/CMakeLists.txt
+++ b/log_writer/log_writer_syslog/CMakeLists.txt
@@ -23,10 +23,6 @@ if (LOG_WRITER_SYSLOG)
         SYMBOLIC_NAME "apache_celix_log_writer_syslog"
         NAME "Apache Celix Log Writer Syslog"
         SOURCES
-
-            #${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/src/log_writer_activator
-            #${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/src/log_writer
-            #${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/include/log_writer.h
             private/src/log_writer_syslog
     )
 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/CMakeLists.txt b/pubsub/CMakeLists.txt
index a866ba4..9d18175 100644
--- a/pubsub/CMakeLists.txt
+++ b/pubsub/CMakeLists.txt
@@ -43,7 +43,7 @@ if (PUBSUB)
 	endif()
 
 	#api target
-	add_libary(pubsub_api INTERFACE)
+	add_library(pubsub_api INTERFACE)
 	target_include_directories(pubsub_api INTERFACE api)
 
 	#install api

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/deploy/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/deploy/CMakeLists.txt b/pubsub/deploy/CMakeLists.txt
index 6f9234d..e76f91b 100644
--- a/pubsub/deploy/CMakeLists.txt
+++ b/pubsub/deploy/CMakeLists.txt
@@ -165,7 +165,7 @@ if (BUILD_PUBSUB_PSA_ZMQ)
 	add_deploy("pubsub_mp_subscriber_zmq"
 	    GROUP "pubsub"
 	    BUNDLES
-			Celix::hell
+			Celix::shell
 			Celix::shell_tui
 	       	org.apache.celix.pubsub_serializer.PubSubSerializerJson
 	       	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt b/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
index 76a01f1..1ef8645 100644
--- a/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
+++ b/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
@@ -47,4 +47,4 @@ bundle_files(org.apache.celix.pubsub_publisher.MpPublisher
     DESTINATION "META-INF/keys/subscriber"
 )
 
-target_link_libraries(org.apache.celix.pubsub_publisher.MpPublisher celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_publisher.MpPublisher PRIVATE Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt b/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
index a480a73..e281ab1 100644
--- a/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
+++ b/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
@@ -47,4 +47,4 @@ bundle_files(org.apache.celix.pubsub_subscriber.MpSubscriber
     DESTINATION "META-INF/keys/publisher"
 )
 
-target_link_libraries(org.apache.celix.pubsub_subscriber.MpSubscriber celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_subscriber.MpSubscriber PRIVATE Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/publisher/CMakeLists.txt b/pubsub/examples/pubsub/publisher/CMakeLists.txt
index e35c137..fcf50c7 100644
--- a/pubsub/examples/pubsub/publisher/CMakeLists.txt
+++ b/pubsub/examples/pubsub/publisher/CMakeLists.txt
@@ -51,4 +51,4 @@ bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
     DESTINATION "META-INF/keys/subscriber"
 )
 
-target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher PRIVATE Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/pubsub/publisher2/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/publisher2/CMakeLists.txt b/pubsub/examples/pubsub/publisher2/CMakeLists.txt
index b83f7dd..82ffb75 100644
--- a/pubsub/examples/pubsub/publisher2/CMakeLists.txt
+++ b/pubsub/examples/pubsub/publisher2/CMakeLists.txt
@@ -51,4 +51,4 @@ bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher2
     DESTINATION "META-INF/keys/subscriber"
 )
 
-target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher2 celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher2 PRIVATE Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/pubsub/subscriber/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/subscriber/CMakeLists.txt b/pubsub/examples/pubsub/subscriber/CMakeLists.txt
index 7fd9fae..28569b0 100644
--- a/pubsub/examples/pubsub/subscriber/CMakeLists.txt
+++ b/pubsub/examples/pubsub/subscriber/CMakeLists.txt
@@ -52,4 +52,4 @@ bundle_files(org.apache.celix.pubsub_subscriber.PoiSubscriber
     DESTINATION "META-INF/keys/publisher"
 )
 
-target_link_libraries(org.apache.celix.pubsub_subscriber.PoiSubscriber celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_subscriber.PoiSubscriber PRIVATE Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/CMakeLists.txt b/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
index 3ab0c54..a57693f 100644
--- a/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
+++ b/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
@@ -17,32 +17,28 @@
 
 find_package(Jansson REQUIRED)
 
-include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/dfi/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("private/include")
-include_directories("public/include")
-include_directories("${JANSSON_INCLUDE_DIR}")
-
 add_bundle(org.apache.celix.pubsub_admin.PubSubAdminUdpMc
 	BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_udp_multicast"
 	VERSION "1.0.0"
 	SOURCES
-		private/src/psa_activator.c
-		private/src/pubsub_admin_impl.c
-		private/src/topic_subscription.c
-		private/src/topic_publication.c
-		private/src/large_udp.c
-	   ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+        src/psa_activator.c
+        src/pubsub_admin_impl.c
+        src/topic_subscription.c
+        src/topic_publication.c
+        src/large_udp.c
 		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
 		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_admin_match.c
 		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
 )
 
+
+target_include_directories(org.apache.celix.pubsub_admin.PubSubAdminUdpMc PRIVATE
+		src
+		${JANSSON_INCLUDE_DIR}
+)
+
 set_target_properties(org.apache.celix.pubsub_admin.PubSubAdminUdpMc PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminUdpMc celix_framework celix_utils celix_dfi)
+target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminUdpMc PRIVATE Celix::framework Celix::dfi Celix::log_helper)
 
 install_bundle(org.apache.celix.pubsub_admin.PubSubAdminUdpMc)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/include/large_udp.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/include/large_udp.h b/pubsub/pubsub_admin_udp_mc/private/include/large_udp.h
deleted file mode 100644
index a21e654..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/include/large_udp.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * large_udp.h
- *
- *  \date       Mar 1, 2016
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef _LARGE_UDP_H_
-#define _LARGE_UDP_H_
-#include <stdbool.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-typedef struct largeUdp  *largeUdp_pt;
-
-largeUdp_pt largeUdp_create(unsigned int maxNrUdpReceptions);
-void largeUdp_destroy(largeUdp_pt handle);
-
-int largeUdp_sendto(largeUdp_pt handle, int fd, void *buf, size_t count, int flags, struct sockaddr_in *dest_addr, size_t addrlen);
-int largeUdp_sendmsg(largeUdp_pt handle, int fd, struct iovec *largeMsg_iovec, int len, int flags, struct sockaddr_in *dest_addr, size_t addrlen);
-bool largeUdp_dataAvailable(largeUdp_pt handle, int fd, unsigned int *index, unsigned int *size);
-int largeUdp_read(largeUdp_pt handle, unsigned int index, void ** buffer, unsigned int size);
-
-#endif /* _LARGE_UDP_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/include/pubsub_admin_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/include/pubsub_admin_impl.h b/pubsub/pubsub_admin_udp_mc/private/include/pubsub_admin_impl.h
deleted file mode 100644
index de4b813..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/include/pubsub_admin_impl.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * pubsub_admin_impl.h
- *
- *  \date       Dec 5, 2013
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_ADMIN_UDP_MC_IMPL_H_
-#define PUBSUB_ADMIN_UDP_MC_IMPL_H_
-
-#include "pubsub_admin.h"
-#include "log_helper.h"
-
-#define PUBSUB_ADMIN_TYPE	"udp_mc"
-
-struct pubsub_admin {
-
-	bundle_context_pt bundle_context;
-	log_helper_pt loghelper;
-
-	/* List of the available serializers */
-	celix_thread_mutex_t serializerListLock; // List<serializers>
-	array_list_pt serializerList;
-
-	celix_thread_mutex_t localPublicationsLock;
-	hash_map_pt localPublications;//<topic(string),service_factory_pt>
-
-	celix_thread_mutex_t externalPublicationsLock;
-	hash_map_pt externalPublications;//<topic(string),List<pubsub_ep>>
-
-	celix_thread_mutex_t subscriptionsLock;
-	hash_map_pt subscriptions; //<topic(string),topic_subscription>
-
-	celix_thread_mutex_t pendingSubscriptionsLock;
-	celix_thread_mutexattr_t pendingSubscriptionsAttr;
-	hash_map_pt pendingSubscriptions; //<topic(string),List<pubsub_ep>>
-
-	/* Those are used to keep track of valid subscriptions/publications that still have no valid serializer */
-	celix_thread_mutex_t noSerializerPendingsLock;
-	celix_thread_mutexattr_t noSerializerPendingsAttr;
-	array_list_pt noSerializerSubscriptions; // List<pubsub_ep>
-	array_list_pt noSerializerPublications; // List<pubsub_ep>
-
-	celix_thread_mutex_t usedSerializersLock;
-	hash_map_pt topicSubscriptionsPerSerializer; // <serializer,List<topicSubscription>>
-	hash_map_pt topicPublicationsPerSerializer; // <serializer,List<topicPublications>>
-
-	char* ifIpAddress; // The local interface which is used for multicast communication
-	char* mcIpAddress; // The multicast IP address
-
-	int sendSocket;
-	void* zmq_context; // to be removed
-
-};
-
-celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin);
-celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin);
-
-celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-
-celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
-celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
-
-celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char* scope, char* topic);
-celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char* scope, char* topic);
-
-celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service);
-celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service);
-
-celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score);
-
-
-#endif /* PUBSUB_ADMIN_UDP_MC_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/include/topic_publication.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/include/topic_publication.h b/pubsub/pubsub_admin_udp_mc/private/include/topic_publication.h
deleted file mode 100644
index 4363d71..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/include/topic_publication.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * topic_publication.h
- *
- *  \date       Sep 24, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef TOPIC_PUBLICATION_H_
-#define TOPIC_PUBLICATION_H_
-
-#include "publisher.h"
-#include "pubsub_endpoint.h"
-#include "pubsub_common.h"
-
-#include "pubsub_serializer.h"
-
-#define UDP_BASE_PORT	49152
-#define UDP_MAX_PORT	65000
-
-typedef struct pubsub_udp_msg {
-    struct pubsub_msg_header header;
-    unsigned int payloadSize;
-    char payload[];
-} pubsub_udp_msg_t;
-
-typedef struct topic_publication *topic_publication_pt;
-celix_status_t pubsub_topicPublicationCreate(int sendSocket, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, topic_publication_pt *out);
-celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub);
-
-celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
-celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
-
-celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory);
-celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub);
-
-array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub);
-
-#endif /* TOPIC_PUBLICATION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/include/topic_subscription.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/include/topic_subscription.h b/pubsub/pubsub_admin_udp_mc/private/include/topic_subscription.h
deleted file mode 100644
index 475416a..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/include/topic_subscription.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * topic_subscription.h
- *
- *  \date       Sep 22, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef TOPIC_SUBSCRIPTION_H_
-#define TOPIC_SUBSCRIPTION_H_
-
-#include "celix_threads.h"
-#include "array_list.h"
-#include "celixbool.h"
-#include "service_tracker.h"
-
-#include "pubsub_endpoint.h"
-#include "pubsub_common.h"
-#include "pubsub_serializer.h"
-
-typedef struct topic_subscription* topic_subscription_pt;
-
-celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* ifIp,char* scope, char* topic ,pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out);
-celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts);
-celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts);
-celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts);
-
-celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
-celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
-
-celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL);
-celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL);
-
-celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
-celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
-
-array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub);
-celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt subscription);
-celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt subscription);
-unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt subscription);
-
-#endif /*TOPIC_SUBSCRIPTION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/large_udp.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/large_udp.c b/pubsub/pubsub_admin_udp_mc/private/src/large_udp.c
deleted file mode 100644
index 7455925..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/large_udp.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * large_udp.c
- *
- *  \date       Mar 1, 2016
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include "large_udp.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <array_list.h>
-#include <pthread.h>
-
-#define MAX_UDP_MSG_SIZE 65535   /* 2^16 -1 */
-#define IP_HEADER_SIZE  20
-#define UDP_HEADER_SIZE 8
-//#define MTU_SIZE    1500
-#define MTU_SIZE    8000
-#define MAX_MSG_VECTOR_LEN 64
-
-//#define NO_IP_FRAGMENTATION
-
-struct largeUdp {
-	unsigned int maxNrLists;
-	array_list_pt udpPartLists;
-	pthread_mutex_t dbLock;
-};
-
-typedef struct udpPartList {
-	unsigned int msg_ident;
-	unsigned int msg_size;
-	unsigned int nrPartsRemaining;
-	char *data;
-} *udpPartList_pt;
-
-
-typedef struct msg_part_header {
-	unsigned int msg_ident;
-	unsigned int total_msg_size;
-	unsigned int part_msg_size;
-	unsigned int offset;
-} msg_part_header_t;
-
-#ifdef NO_IP_FRAGMENTATION
-#define MAX_PART_SIZE   (MTU_SIZE - (IP_HEADER_SIZE + UDP_HEADER_SIZE + sizeof(struct msg_part_header) ))
-#else
-#define MAX_PART_SIZE   (MAX_UDP_MSG_SIZE - (IP_HEADER_SIZE + UDP_HEADER_SIZE + sizeof(struct msg_part_header) ))
-#endif
-
-typedef struct msg_part {
-	msg_part_header_t header;
-	char data[MAX_PART_SIZE];
-} msg_part_t;
-
-//
-// Create a handle
-//
-largeUdp_pt largeUdp_create(unsigned int maxNrUdpReceptions)
-{
-	printf("## Creating large UDP\n");
-	largeUdp_pt handle = calloc(sizeof(*handle), 1);
-	if(handle != NULL) {
-		handle->maxNrLists = maxNrUdpReceptions;
-		if(arrayList_create(&handle->udpPartLists) != CELIX_SUCCESS) {
-			free(handle);
-			handle = NULL;
-		}
-		pthread_mutex_init(&handle->dbLock, 0);
-	}
-
-	return handle;
-}
-
-//
-// Destroys the handle
-//
-void largeUdp_destroy(largeUdp_pt handle)
-{
-	printf("### Destroying large UDP\n");
-	if(handle != NULL) {
-		pthread_mutex_lock(&handle->dbLock);
-		int nrUdpLists = arrayList_size(handle->udpPartLists);
-		int i;
-		for(i=0; i < nrUdpLists; i++) {
-			udpPartList_pt udpPartList = arrayList_remove(handle->udpPartLists, i);
-			if(udpPartList) {
-				if(udpPartList->data) {
-					free(udpPartList->data);
-					udpPartList->data = NULL;
-				}
-				free(udpPartList);
-			}
-		}
-		arrayList_destroy(handle->udpPartLists);
-		handle->udpPartLists = NULL;
-		pthread_mutex_unlock(&handle->dbLock);
-		pthread_mutex_destroy(&handle->dbLock);
-		free(handle);
-	}
-}
-
-//
-// Write large data to UDP. This function splits the data in chunks and sends these chunks with a header over UDP.
-//
-int largeUdp_sendmsg(largeUdp_pt handle, int fd, struct iovec *largeMsg_iovec, int len, int flags, struct sockaddr_in *dest_addr, size_t addrlen)
-{
-	int n;
-	int result = 0;
-	msg_part_header_t header;
-
-	int written = 0;
-	header.msg_ident = (unsigned int)random();
-	header.total_msg_size = 0;
-	for(n = 0; n < len ;n++) {
-		header.total_msg_size += largeMsg_iovec[n].iov_len;
-	}
-	int nr_buffers = (header.total_msg_size / MAX_PART_SIZE) + 1;
-
-	struct iovec msg_iovec[MAX_MSG_VECTOR_LEN];
-	struct msghdr msg;
-	msg.msg_name = dest_addr;
-	msg.msg_namelen = addrlen;
-	msg.msg_flags = 0;
-	msg.msg_iov = msg_iovec;
-	msg.msg_iovlen = 2; // header and payload;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-
-	msg.msg_iov[0].iov_base = &header;
-	msg.msg_iov[0].iov_len = sizeof(header);
-
-	for(n = 0; n < nr_buffers; n++) {
-
-		header.part_msg_size = (((header.total_msg_size - n * MAX_PART_SIZE) >  MAX_PART_SIZE) ?  MAX_PART_SIZE  : (header.total_msg_size - n * MAX_PART_SIZE));
-		header.offset = n * MAX_PART_SIZE;
-		int remainingOffset = header.offset;
-		int recvPart = 0;
-		// find the start of the part
-		while(remainingOffset > largeMsg_iovec[recvPart].iov_len) {
-			remainingOffset -= largeMsg_iovec[recvPart].iov_len;
-			recvPart++;
-		}
-		int remainingData = header.part_msg_size;
-		int sendPart = 1;
-		msg.msg_iovlen = 1;
-
-		// fill in the output iovec from the input iovec in such a way that all UDP frames are filled maximal.
-		while(remainingData > 0) {
-			int partLen = ( (largeMsg_iovec[recvPart].iov_len - remainingOffset) <= remainingData ? (largeMsg_iovec[recvPart].iov_len -remainingOffset) : remainingData);
-			msg.msg_iov[sendPart].iov_base = largeMsg_iovec[recvPart].iov_base + remainingOffset;
-			msg.msg_iov[sendPart].iov_len = partLen;
-			remainingData -= partLen;
-			remainingOffset = 0;
-			sendPart++;
-			recvPart++;
-			msg.msg_iovlen++;
-		}
-		int tmp, tmptot;
-		for(tmp = 0, tmptot=0; tmp < msg.msg_iovlen; tmp++) {
-			tmptot += msg.msg_iov[tmp].iov_len;
-		}
-
-		int w = sendmsg(fd, &msg, 0);
-		if(w == -1) {
-			perror("send()");
-			result =  -1;
-			break;
-		}
-		written += w;
-	}
-
-	return (result == 0 ? written : result);
-}
-
-//
-// Write large data to UDP. This function splits the data in chunks and sends these chunks with a header over UDP.
-//
-int largeUdp_sendto(largeUdp_pt handle, int fd, void *buf, size_t count, int flags, struct sockaddr_in *dest_addr, size_t addrlen)
-{
-	int n;
-	int nr_buffers = (count / MAX_PART_SIZE) + 1;
-	int result = 0;
-	msg_part_header_t header;
-
-	int written = 0;
-	header.msg_ident = (unsigned int)random();
-	header.total_msg_size = count;
-	char *databuf = buf;
-
-	struct iovec msg_iovec[2];
-	struct msghdr msg;
-	msg.msg_name = dest_addr;
-	msg.msg_namelen = addrlen;
-	msg.msg_flags = 0;
-	msg.msg_iov = msg_iovec;
-	msg.msg_iovlen = 2; // header and payload;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-
-	msg.msg_iov[0].iov_base = &header;
-	msg.msg_iov[0].iov_len = sizeof(header);
-
-	for(n = 0; n < nr_buffers; n++) {
-
-		header.part_msg_size = (((header.total_msg_size - n * MAX_PART_SIZE) >  MAX_PART_SIZE) ?  MAX_PART_SIZE  : (header.total_msg_size - n * MAX_PART_SIZE));
-		header.offset = n * MAX_PART_SIZE;
-		msg.msg_iov[1].iov_base = &databuf[header.offset];
-		msg.msg_iov[1].iov_len = header.part_msg_size;
-		int w = sendmsg(fd, &msg, 0);
-		if(w == -1) {
-			perror("send()");
-			result =  -1;
-			break;
-		}
-		written += w;
-		//usleep(1000); // TODO: If not slept a UDP buffer overflow occurs and parts are missing at the reception side (at least via localhost)
-	}
-
-	return (result == 0 ? written : result);
-}
-
-//
-// Reads data from the filedescriptor which has date (determined by epoll()) and stores it in the internal structure
-// If the message is completely reassembled true is returned and the index and size have valid values
-//
-bool largeUdp_dataAvailable(largeUdp_pt handle, int fd, unsigned int *index, unsigned int *size) {
-	msg_part_header_t header;
-	int result = false;
-	// Only read the header, we don't know yet where to store the payload
-	if(recv(fd, &header, sizeof(header), MSG_PEEK) < 0) {
-		perror("read()");
-		return false;
-	}
-
-	struct iovec msg_vec[2];
-	struct msghdr msg;
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_flags = 0;
-	msg.msg_iov = msg_vec;
-	msg.msg_iovlen = 2; // header and payload;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-
-	msg.msg_iov[0].iov_base = &header;
-	msg.msg_iov[0].iov_len = sizeof(header);
-
-	pthread_mutex_lock(&handle->dbLock);
-
-	int nrUdpLists = arrayList_size(handle->udpPartLists);
-	int i;
-	bool found = false;
-	for(i = 0; i < nrUdpLists; i++) {
-		udpPartList_pt udpPartList = arrayList_get(handle->udpPartLists, i);
-		if(udpPartList->msg_ident == header.msg_ident) {
-			found = true;
-
-			//sanity check
-			if(udpPartList->msg_size != header.total_msg_size) {
-				// Corruption occurred. Remove the existing administration and build up a new one.
-				arrayList_remove(handle->udpPartLists, i);
-				free(udpPartList->data);
-				free(udpPartList);
-				found = false;
-				break;
-			}
-
-			msg.msg_iov[1].iov_base = &udpPartList->data[header.offset];
-			msg.msg_iov[1].iov_len = header.part_msg_size;
-			if(recvmsg(fd, &msg, 0)<0){
-				found=true;
-				result=false;
-				break;
-			}
-
-			udpPartList->nrPartsRemaining--;
-			if(udpPartList->nrPartsRemaining == 0) {
-				*index = i;
-				*size = udpPartList->msg_size;
-				result = true;
-				break;
-			} else {
-				result = false; // not complete
-				break;
-			}
-		}
-	}
-
-	if(found == false) {
-		udpPartList_pt udpPartList = NULL;
-		if(nrUdpLists == handle->maxNrLists) {
-			// remove list at index 0
-			udpPartList = arrayList_remove(handle->udpPartLists, 0);
-			fprintf(stderr, "ERROR: Removing entry for id %d: %d parts not received\n",udpPartList->msg_ident, udpPartList->nrPartsRemaining );
-			free(udpPartList->data);
-			free(udpPartList);
-			nrUdpLists--;
-		}
-		udpPartList = calloc(sizeof(*udpPartList), 1);
-		udpPartList->msg_ident =  header.msg_ident;
-		udpPartList->msg_size =  header.total_msg_size;
-		udpPartList->nrPartsRemaining = header.total_msg_size / MAX_PART_SIZE;
-		udpPartList->data = calloc(sizeof(char), header.total_msg_size);
-
-		msg.msg_iov[1].iov_base = &udpPartList->data[header.offset];
-		msg.msg_iov[1].iov_len = header.part_msg_size;
-		if(recvmsg(fd, &msg, 0)<0){
-			free(udpPartList->data);
-			free(udpPartList);
-			result=false;
-		}
-		else{
-			arrayList_add(handle->udpPartLists, udpPartList);
-
-			if(udpPartList->nrPartsRemaining == 0) {
-				*index = nrUdpLists;
-				*size = udpPartList->msg_size;
-				result = true;
-			} else {
-				result = false;
-			}
-		}
-
-	}
-
-	pthread_mutex_unlock(&handle->dbLock);
-
-	return result;
-}
-
-//
-// Read out the message which is indicated available by the largeUdp_dataAvailable function
-//
-int largeUdp_read(largeUdp_pt handle, unsigned int index, void ** buffer, unsigned int size)
-{
-	int result = 0;
-	pthread_mutex_lock(&handle->dbLock);
-
-	udpPartList_pt udpPartList = arrayList_remove(handle->udpPartLists, index);
-	if(udpPartList) {
-		*buffer = udpPartList->data;
-		free(udpPartList);
-	} else {
-		result = -1;
-	}
-	pthread_mutex_unlock(&handle->dbLock);
-
-	return result;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/psa_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/psa_activator.c b/pubsub/pubsub_admin_udp_mc/private/src/psa_activator.c
deleted file mode 100644
index cd4ee07..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/psa_activator.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * psa_activator.c
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-#include "service_tracker.h"
-
-#include "pubsub_admin_impl.h"
-
-struct activator {
-	pubsub_admin_pt admin;
-	pubsub_admin_service_pt adminService;
-	service_registration_pt registration;
-	service_tracker_pt serializerTracker;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator;
-
-	activator = calloc(1, sizeof(*activator));
-	if (!activator) {
-		status = CELIX_ENOMEM;
-	}
-	else{
-		*userData = activator;
-
-		status = pubsubAdmin_create(context, &(activator->admin));
-
-		if(status == CELIX_SUCCESS){
-			service_tracker_customizer_pt customizer = NULL;
-			status = serviceTrackerCustomizer_create(activator->admin,
-					NULL,
-					pubsubAdmin_serializerAdded,
-					NULL,
-					pubsubAdmin_serializerRemoved,
-					&customizer);
-			if(status == CELIX_SUCCESS){
-				status = serviceTracker_create(context, PUBSUB_SERIALIZER_SERVICE, customizer, &(activator->serializerTracker));
-				if(status != CELIX_SUCCESS){
-					serviceTrackerCustomizer_destroy(customizer);
-					pubsubAdmin_destroy(activator->admin);
-				}
-			}
-			else{
-				pubsubAdmin_destroy(activator->admin);
-			}
-		}
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	pubsub_admin_service_pt pubsubAdminSvc = calloc(1, sizeof(*pubsubAdminSvc));
-
-	if (!pubsubAdminSvc) {
-		status = CELIX_ENOMEM;
-	}
-	else{
-		pubsubAdminSvc->admin = activator->admin;
-
-		pubsubAdminSvc->addPublication = pubsubAdmin_addPublication;
-		pubsubAdminSvc->removePublication = pubsubAdmin_removePublication;
-
-		pubsubAdminSvc->addSubscription = pubsubAdmin_addSubscription;
-		pubsubAdminSvc->removeSubscription = pubsubAdmin_removeSubscription;
-
-		pubsubAdminSvc->closeAllPublications = pubsubAdmin_closeAllPublications;
-		pubsubAdminSvc->closeAllSubscriptions = pubsubAdmin_closeAllSubscriptions;
-
-		pubsubAdminSvc->matchEndpoint = pubsubAdmin_matchEndpoint;
-
-		activator->adminService = pubsubAdminSvc;
-
-		status = bundleContext_registerService(context, PUBSUB_ADMIN_SERVICE, pubsubAdminSvc, NULL, &activator->registration);
-
-		status += serviceTracker_open(activator->serializerTracker);
-
-	}
-
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	status += serviceTracker_close(activator->serializerTracker);
-	status += serviceRegistration_unregister(activator->registration);
-
-	activator->registration = NULL;
-
-	free(activator->adminService);
-	activator->adminService = NULL;
-
-	return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	serviceTracker_destroy(activator->serializerTracker);
-	pubsubAdmin_destroy(activator->admin);
-	activator->admin = NULL;
-
-	free(activator);
-
-	return status;
-}
-
-


[07/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/export_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/export_registration_impl.c b/remote_services/remote_service_admin_common/src/export_registration_impl.c
new file mode 100644
index 0000000..1c684e7
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/export_registration_impl.c
@@ -0,0 +1,257 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * export_registration_impl.c
+ *
+ *  \date       Oct 6, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "constants.h"
+
+#include "celix_errno.h"
+
+#include "export_registration_impl.h"
+#include "remote_service_admin_impl.h"
+
+
+struct export_reference {
+	endpoint_description_pt endpoint;
+	service_reference_pt reference;
+};
+
+celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service);
+celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *service);
+celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service);
+celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service);
+
+celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker);
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*registration = calloc(1, sizeof(**registration));
+	if (!*registration) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*registration)->context = context;
+		(*registration)->closed = false;
+		(*registration)->endpointDescription = endpoint;
+		(*registration)->reference = reference;
+		(*registration)->rsa = rsa;
+		(*registration)->tracker = NULL;
+		(*registration)->endpoint = NULL;
+		(*registration)->endpointTracker = NULL;
+		(*registration)->exportReference = NULL;
+		(*registration)->bundle = NULL;
+		(*registration)->loghelper = helper;
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_destroy(export_registration_pt *registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	remoteServiceAdmin_destroyEndpointDescription(&(*registration)->endpointDescription);
+	free(*registration);
+
+	return status;
+}
+
+celix_status_t exportRegistration_startTracking(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->endpointTracker == NULL) {
+		status = exportRegistration_createEndpointTracker(registration, &registration->endpointTracker);
+		if (status == CELIX_SUCCESS) {
+			status = serviceTracker_open(registration->endpointTracker);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_stopTracking(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->endpointTracker != NULL) {
+		status = serviceTracker_close(registration->endpointTracker);
+		if (status != CELIX_SUCCESS) {
+		    logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close endpoint tracker");
+		}
+		else {
+			status = serviceTracker_destroy(registration->endpointTracker);
+		}
+	}
+	if (registration->tracker != NULL) {
+		status = serviceTracker_close(registration->tracker);
+		if (status != CELIX_SUCCESS) {
+			logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close service tracker");
+		}
+		else {
+			status = serviceTracker_destroy(registration->tracker);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker) {
+	celix_status_t status;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(registration, exportRegistration_endpointAdding,
+			exportRegistration_endpointAdded, exportRegistration_endpointModified, exportRegistration_endpointRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		char filter[512];
+
+		snprintf(filter, 512, "(&(%s=%s)(remote.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_ENDPOINT, registration->endpointDescription->service);
+		status = serviceTracker_createWithFilter(registration->context, filter, customizer, tracker);
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status;
+	export_registration_pt registration = handle;
+
+	status = bundleContext_getService(registration->context, reference, service);
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *endpoint_service) {
+	celix_status_t status = CELIX_SUCCESS;
+	export_registration_pt registration = handle;
+
+	remote_endpoint_service_pt endpoint = endpoint_service;
+	if (registration->endpoint == NULL) {
+		registration->endpoint = endpoint;
+		void *service = NULL;
+		status = bundleContext_getService(registration->context, registration->reference, &service);
+		if (status == CELIX_SUCCESS) {
+			endpoint->setService(endpoint->endpoint, service);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	export_registration_pt registration = handle;
+
+	remote_endpoint_service_pt endpoint = service;
+	if (registration->endpoint != NULL) {
+		endpoint->setService(endpoint->endpoint, NULL);
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_open(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	const char *bundleStore = NULL;
+
+	bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
+
+	if (bundleStore == NULL) {
+		bundleStore = DEFAULT_BUNDLE_STORE;
+	}
+	char name[256];
+
+	snprintf(name, 256, "%s/%s_endpoint.zip", bundleStore, registration->endpointDescription->service);
+
+	status = bundleContext_installBundle(registration->context, name, &registration->bundle);
+	if (status == CELIX_SUCCESS) {
+		status = bundle_start(registration->bundle);
+		if (status == CELIX_SUCCESS) {
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_close(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	exportRegistration_stopTracking(registration);
+
+	bundle_uninstall(registration->bundle);
+
+
+	return status;
+}
+
+celix_status_t exportRegistration_getException(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	registration->exportReference = calloc(1, sizeof(*registration->exportReference));
+
+	if (registration->exportReference == NULL) {
+		status = CELIX_ENOMEM;
+	} else {
+		registration->exportReference->endpoint = registration->endpointDescription;
+		registration->exportReference->reference = registration->reference;
+	}
+	
+	*reference = registration->exportReference;
+
+	return status;
+}
+
+celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	registration->endpointDescription = endpointDescription;
+
+	return status;
+}
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*endpoint = reference->endpoint;
+
+	return status;
+}
+
+celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	*service = reference->reference;
+	return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/export_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/export_registration_impl.h b/remote_services/remote_service_admin_common/src/export_registration_impl.h
new file mode 100644
index 0000000..bb276f9
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/export_registration_impl.h
@@ -0,0 +1,61 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * export_registration_impl.h
+ *
+ *  \date       Oct 6, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef EXPORT_REGISTRATION_IMPL_H_
+#define EXPORT_REGISTRATION_IMPL_H_
+
+#include "remote_service_admin.h"
+#include "remote_endpoint.h"
+#include "service_tracker.h"
+#include "log_helper.h"
+
+struct export_registration {
+	bundle_context_pt context;
+	remote_service_admin_pt rsa;
+	endpoint_description_pt endpointDescription;
+	service_reference_pt reference;
+	log_helper_pt loghelper;
+
+	service_tracker_pt tracker;
+	service_tracker_pt endpointTracker;
+
+	remote_endpoint_service_pt endpoint;
+
+	export_reference_pt exportReference;
+	bundle_pt bundle;
+
+	bool closed;
+};
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration);
+celix_status_t exportRegistration_destroy(export_registration_pt *registration);
+celix_status_t exportRegistration_open(export_registration_pt registration);
+
+celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription);
+celix_status_t exportRegistration_startTracking(export_registration_pt registration);
+celix_status_t exportRegistration_stopTracking(export_registration_pt registration);
+
+#endif /* EXPORT_REGISTRATION_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/import_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/import_registration_impl.c b/remote_services/remote_service_admin_common/src/import_registration_impl.c
new file mode 100644
index 0000000..9a84327
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/import_registration_impl.c
@@ -0,0 +1,274 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * import_registration_impl.c
+ *
+ *  \date       Oct 14, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <constants.h>
+
+#include "celix_errno.h"
+
+#include "import_registration_impl.h"
+#include "remote_service_admin_impl.h"
+
+struct import_reference {
+	endpoint_description_pt endpoint;
+	service_reference_pt reference;
+};
+
+
+
+celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service);
+celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service);
+celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service);
+celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service);
+
+celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle sendToCallback, bundle_context_pt context, import_registration_pt *registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*registration = calloc(1, sizeof(**registration));
+	if (!*registration) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*registration)->context = context;
+		(*registration)->closed = false;
+		(*registration)->endpointDescription = endpoint;
+		(*registration)->rsa = rsa;
+		(*registration)->sendToCallback = sendToCallback;
+		(*registration)->reference = NULL;
+		(*registration)->importReference = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_destroy(import_registration_pt registration)
+{
+	free(registration);
+
+	return CELIX_SUCCESS;
+}
+
+
+celix_status_t importRegistrationFactory_create(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*registration_factory = calloc(1, sizeof(**registration_factory));
+	if (!*registration_factory) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*registration_factory)->serviceName = strdup(serviceName);
+		(*registration_factory)->context = context;
+		(*registration_factory)->bundle = NULL;
+		(*registration_factory)->loghelper = helper;
+
+		arrayList_create(&(*registration_factory)->registrations);
+	}
+
+	return status;
+}
+
+
+
+celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (*registration_factory != NULL)
+	{
+		free((*registration_factory)->serviceName);
+		arrayList_destroy((*registration_factory)->registrations);
+
+		serviceTracker_destroy((*registration_factory)->proxyFactoryTracker);
+		free(*registration_factory);
+
+		*registration_factory = NULL;
+	}
+
+
+	return status;
+}
+
+
+celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory)
+{
+	celix_status_t status;
+
+	const char *bundleStore = NULL;
+	bundleContext_getProperty(registration_factory->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
+
+	if (bundleStore == NULL) {
+		bundleStore = DEFAULT_BUNDLE_STORE;
+	}
+
+	char name[256];
+	snprintf(name, 256, "%s/%s_proxy.zip", bundleStore, registration_factory->serviceName);
+
+	status = bundleContext_installBundle(registration_factory->context, name, &registration_factory->bundle);
+
+	if (status == CELIX_SUCCESS) {
+		status = bundle_start(registration_factory->bundle);
+		if (status == CELIX_SUCCESS) {
+			logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_INFO, "%s successfully started.", name);
+		}
+	}
+	else {
+		logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_ERROR, "%s could not be installed.", name);
+	}
+
+	return status;
+}
+
+celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory)
+{
+	celix_status_t status = CELIX_SUCCESS;
+
+
+	if (registration_factory->proxyFactoryTracker != NULL) {
+		serviceTracker_close(registration_factory->proxyFactoryTracker);
+	}
+
+	if (registration_factory->bundle != NULL) {
+		bundle_uninstall(registration_factory->bundle);
+	}
+
+	return status;
+}
+
+
+celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker) {
+	celix_status_t status;
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(registration_factory, importRegistration_proxyFactoryAdding, importRegistration_proxyFactoryAdded, importRegistration_proxyFactoryModified, importRegistration_proxyFactoryRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		char filter[512];
+
+		snprintf(filter, 512, "(&(%s=%s)(proxy.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_PROXY_FACTORY, registration_factory->serviceName);
+		status = serviceTracker_createWithFilter(registration_factory->context, filter, customizer, tracker);
+
+		if (status == CELIX_SUCCESS)
+		{
+			serviceTracker_open(*tracker);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
+
+	bundleContext_getService(registration_factory->context, reference, service);
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
+	registration_factory->trackedFactory = (remote_proxy_factory_service_pt) service;
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
+	registration_factory->trackedFactory = NULL;
+
+	return status;
+}
+
+
+
+celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory)
+{
+	celix_status_t status;
+
+	if ( (status = importRegistrationFactory_create(helper, serviceName, context, registration_factory)) == CELIX_SUCCESS) {
+		// starting the proxy tracker first allows us to pick up already available proxy factories
+		importRegistration_createProxyFactoryTracker(*registration_factory, &((*registration_factory)->proxyFactoryTracker));
+		logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_INFO, "remoteServiceAdmin_importService: new registration_factory added for %s at %p", serviceName, (*registration_factory)->proxyFactoryTracker);
+
+		// check whether factory is available
+		if (((*registration_factory)->trackedFactory == NULL) && ((status = importRegistrationFactory_open(*registration_factory)) != CELIX_SUCCESS)) {
+			logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_ERROR, "remoteServiceAdmin_importService: cannot open registration_factory for %s.", serviceName);
+
+			importRegistrationFactory_close(*registration_factory);
+			importRegistrationFactory_destroy(registration_factory);
+		}
+	}
+
+	return status;
+}
+
+
+
+
+celix_status_t importRegistration_getException(import_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->importReference == NULL) {
+		registration->importReference = calloc(1, sizeof(*registration->importReference));
+		if (registration->importReference == NULL) {
+			status = CELIX_ENOMEM;
+		} else {
+			registration->importReference->endpoint = registration->endpointDescription;
+			registration->importReference->reference = registration->reference;
+		}
+	}
+
+	*reference = registration->importReference;
+
+	return status;
+}
+
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+celix_status_t importReference_getImportedService(import_reference_pt reference) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/import_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/import_registration_impl.h b/remote_services/remote_service_admin_common/src/import_registration_impl.h
new file mode 100644
index 0000000..7aa397f
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/import_registration_impl.h
@@ -0,0 +1,81 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * import_registration_impl.h
+ *
+ *  \date       Oct 14, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef IMPORT_REGISTRATION_IMPL_H_
+#define IMPORT_REGISTRATION_IMPL_H_
+
+#include "remote_service_admin.h"
+#include "remote_proxy.h"
+#include "service_tracker.h"
+#include "log_helper.h"
+
+struct import_registration {
+	bundle_context_pt context;
+	endpoint_description_pt endpointDescription;
+
+	service_reference_pt reference;
+	import_reference_pt importReference;
+
+	remote_service_admin_pt rsa;
+	sendToHandle sendToCallback;
+
+	bool closed;
+};
+
+
+
+struct import_registration_factory
+{
+	char* serviceName;
+	log_helper_pt loghelper;
+	remote_proxy_factory_service_pt trackedFactory;
+	service_tracker_pt proxyFactoryTracker;
+	bundle_context_pt context;
+	array_list_pt registrations;
+	bundle_pt bundle;
+};
+
+
+celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle callback, bundle_context_pt context, import_registration_pt *registration);
+celix_status_t importRegistration_destroy(import_registration_pt registration);
+
+celix_status_t importRegistration_setEndpointDescription(import_registration_pt registration, endpoint_description_pt endpointDescription);
+celix_status_t importRegistration_setHandler(import_registration_pt registration, void * handler);
+celix_status_t importRegistration_setCallback(import_registration_pt registration, sendToHandle callback);
+
+celix_status_t importRegistration_getException(import_registration_pt registration);
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference);
+
+celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker);
+
+celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory);
+//celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory);
+celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory);
+celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory);
+
+
+
+#endif /* IMPORT_REGISTRATION_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c b/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c
new file mode 100644
index 0000000..9f996d6
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c
@@ -0,0 +1,252 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * remote_proxy_factory_impl.c
+ *
+ *  \date       22 Dec 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "remote_proxy.h"
+
+typedef struct proxy_instance {
+	service_registration_pt registration_ptr;
+	void *service;
+	properties_pt properties;
+} *proxy_instance_pt;
+
+static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback);
+static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription);
+
+celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
+		createProxyService create, destroyProxyService destroy,
+		remote_proxy_factory_pt *remote_proxy_factory_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*remote_proxy_factory_ptr = calloc(1, sizeof(**remote_proxy_factory_ptr));
+	if (!*remote_proxy_factory_ptr) {
+		status = CELIX_ENOMEM;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		(*remote_proxy_factory_ptr)->context_ptr = context;
+		(*remote_proxy_factory_ptr)->service = strdup(service);
+
+		(*remote_proxy_factory_ptr)->remote_proxy_factory_service_ptr = NULL;
+		(*remote_proxy_factory_ptr)->properties = NULL;
+		(*remote_proxy_factory_ptr)->registration = NULL;
+
+		(*remote_proxy_factory_ptr)->proxy_instances = hashMap_create(NULL, NULL, NULL, NULL);
+
+		(*remote_proxy_factory_ptr)->handle = handle;
+
+		(*remote_proxy_factory_ptr)->create_proxy_service_ptr = create;
+		(*remote_proxy_factory_ptr)->destroy_proxy_service_ptr = destroy;
+	}
+
+	return status;
+}
+
+celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!*remote_proxy_factory_ptr) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		if ((*remote_proxy_factory_ptr)->proxy_instances) {
+			hashMap_destroy((*remote_proxy_factory_ptr)->proxy_instances, false, false);
+			(*remote_proxy_factory_ptr)->proxy_instances = NULL;
+		}
+		if ((*remote_proxy_factory_ptr)->service) {
+			free((*remote_proxy_factory_ptr)->service);
+			(*remote_proxy_factory_ptr)->service = NULL;
+		}
+		free(*remote_proxy_factory_ptr);
+		*remote_proxy_factory_ptr = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	remote_proxy_factory_ptr->remote_proxy_factory_service_ptr = calloc(1, sizeof(*remote_proxy_factory_ptr->remote_proxy_factory_service_ptr));
+	if (!remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
+		status = CELIX_ENOMEM;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->factory = remote_proxy_factory_ptr;
+		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->registerProxyService = remoteProxyFactory_registerProxyService;
+		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->unregisterProxyService = remoteProxyFactory_unregisterProxyService;
+
+		remote_proxy_factory_ptr->properties = properties_create();
+		if (!remote_proxy_factory_ptr->properties) {
+			status = CELIX_BUNDLE_EXCEPTION;
+		} else {
+			properties_set(remote_proxy_factory_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+		status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, OSGI_RSA_REMOTE_PROXY_FACTORY,
+				remote_proxy_factory_ptr->remote_proxy_factory_service_ptr, remote_proxy_factory_ptr->properties, &remote_proxy_factory_ptr->registration);
+	}
+
+	return status;
+}
+
+celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!remote_proxy_factory_ptr) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	// #TODO Remove proxy registrations
+	if (status == CELIX_SUCCESS) {
+
+		hash_map_iterator_pt iter = hashMapIterator_create(remote_proxy_factory_ptr->proxy_instances);
+		while(hashMapIterator_hasNext(iter)){
+			proxy_instance_pt proxy_instance_ptr = (proxy_instance_pt)hashMapIterator_nextValue(iter);
+
+			if (proxy_instance_ptr->service) {
+				remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
+			}
+			free(proxy_instance_ptr);
+		}
+		hashMapIterator_destroy(iter);
+
+		if (remote_proxy_factory_ptr->registration) {
+			status = serviceRegistration_unregister(remote_proxy_factory_ptr->registration);
+			remote_proxy_factory_ptr->properties = NULL;
+		}
+		if (remote_proxy_factory_ptr->properties) {
+			properties_destroy(remote_proxy_factory_ptr->properties);
+		}
+		if (remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
+			free(remote_proxy_factory_ptr->remote_proxy_factory_service_ptr);
+		}
+	}
+
+	return status;
+}
+
+
+static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback) {
+	celix_status_t status = CELIX_SUCCESS;
+	proxy_instance_pt proxy_instance_ptr = NULL;
+
+	if (!remote_proxy_factory_ptr || !remote_proxy_factory_ptr->create_proxy_service_ptr) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		proxy_instance_ptr = calloc(1, sizeof(*proxy_instance_ptr));
+		if (!proxy_instance_ptr) {
+			status = CELIX_ENOMEM;
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+		proxy_instance_ptr->properties = properties_create();
+		if (!proxy_instance_ptr->properties) {
+			status = CELIX_ENOMEM;
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+		status = remote_proxy_factory_ptr->create_proxy_service_ptr(remote_proxy_factory_ptr->handle, endpointDescription, rsa, sendToCallback, proxy_instance_ptr->properties, &proxy_instance_ptr->service);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		properties_set(proxy_instance_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
+
+		hash_map_iterator_pt iter = hashMapIterator_create(endpointDescription->properties);
+		while (hashMapIterator_hasNext(iter)) {
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+			char *key = hashMapEntry_getKey(entry);
+			char *value = hashMapEntry_getValue(entry);
+
+			properties_set(proxy_instance_ptr->properties, key, value);
+		}
+		hashMapIterator_destroy(iter);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, remote_proxy_factory_ptr->service, proxy_instance_ptr->service, proxy_instance_ptr->properties, &proxy_instance_ptr->registration_ptr);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		hashMap_put(remote_proxy_factory_ptr->proxy_instances, endpointDescription, proxy_instance_ptr);
+	}
+
+	if(status!=CELIX_SUCCESS){
+		if(proxy_instance_ptr != NULL){
+			if(proxy_instance_ptr->properties != NULL){
+				properties_destroy(proxy_instance_ptr->properties);
+			}
+			free(proxy_instance_ptr);
+		}
+	}
+
+	return status;
+}
+
+static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription) {
+	celix_status_t status = CELIX_SUCCESS;
+	proxy_instance_pt proxy_instance_ptr = NULL;
+
+	if (!remote_proxy_factory_ptr || !endpointDescription || !remote_proxy_factory_ptr->proxy_instances || !remote_proxy_factory_ptr->handle) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		proxy_instance_ptr = hashMap_remove(remote_proxy_factory_ptr->proxy_instances, endpointDescription);
+		if (proxy_instance_ptr == NULL) {
+			status = CELIX_BUNDLE_EXCEPTION;
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+		if (proxy_instance_ptr->registration_ptr) {
+			status = serviceRegistration_unregister(proxy_instance_ptr->registration_ptr);
+			proxy_instance_ptr->properties = NULL;
+		}
+		if (proxy_instance_ptr->service) {
+			status = remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
+		}
+		if (proxy_instance_ptr->properties) {
+			properties_destroy(proxy_instance_ptr->properties);
+		}
+        free(proxy_instance_ptr);
+	}
+
+	return status;
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h b/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h
new file mode 100644
index 0000000..e8a5e1f
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h
@@ -0,0 +1,49 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_impl.h
+ *
+ *  \date       Dec 5, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_IMPL_H_
+
+#include "remote_service_admin.h"
+
+#define BUNDLE_STORE_PROPERTY_NAME "ENDPOINTS"
+#define DEFAULT_BUNDLE_STORE "endpoints"
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
+
+celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *methodSignature, char **reply, int* replyStatus);
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration);
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
+
+#endif /* REMOTE_SERVICE_ADMIN_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
index 01ab9bd..3efabf8 100644
--- a/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
@@ -15,33 +15,20 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories(
-    private/include
-    ${PROJECT_SOURCE_DIR}/utils/public/include
-    ${PROJECT_SOURCE_DIR}/log_service/public/include
-    ${PROJECT_SOURCE_DIR}/remote_services/utils/private/include
-    ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include
-    ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/include
-    ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_http/private/include
-    ${PROJECT_SOURCE_DIR}/dfi/public/include
-    ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_service/public/include
-)
-
 add_bundle(remote_service_admin_dfi 
     VERSION 0.9.0
     SYMBOLIC_NAME "apache_celix_remote_service_admin_dfi"
     NAME "Apache Celix Remote Service Admin Dynamic Function Interface (DFI)"
     SOURCES
-    private/src/remote_service_admin_dfi.c
-    private/src/remote_service_admin_activator.c
-    private/src/export_registration_dfi.c
-    private/src/import_registration_dfi.c
-    private/src/dfi_utils.c
-
-    ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
-
-    ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
+        src/remote_service_admin_dfi.c
+        src/remote_service_admin_activator.c
+        src/export_registration_dfi.c
+        src/import_registration_dfi.c
+        src/dfi_utils.c
 )
-target_link_libraries(remote_service_admin_dfi PRIVATE Celix::dfi Celix::log_helper ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
+target_include_directories(remote_service_admin_dfi PRIVATE src)
+target_link_libraries(remote_service_admin_dfi PRIVATE
+        Celix::dfi Celix::log_helper remote_service_admin_common
+        ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
 
 install_bundle(remote_service_admin_dfi)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/include/dfi_utils.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/include/dfi_utils.h b/remote_services/remote_service_admin_dfi/rsa/private/include/dfi_utils.h
deleted file mode 100644
index cec8aa1..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/include/dfi_utils.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-#ifndef DFI_UTILS_H_
-#define DFI_UTILS_H_
-
-#include "bundle.h"
-#include "bundle_context.h"
-#include <stdio.h>
-#include "celix_errno.h"
-
-
-celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out);
-
-#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/include/export_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/include/export_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/private/include/export_registration_dfi.h
deleted file mode 100644
index 93f37ba..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/include/export_registration_dfi.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef CELIX_EXPORT_REGISTRATION_DFI_H
-#define CELIX_EXPORT_REGISTRATION_DFI_H
-
-
-#include "export_registration.h"
-#include "log_helper.h"
-#include "endpoint_description.h"
-
-celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *registration);
-celix_status_t exportRegistration_close(export_registration_pt registration);
-void exportRegistration_destroy(export_registration_pt registration);
-
-celix_status_t exportRegistration_start(export_registration_pt registration);
-celix_status_t exportRegistration_stop(export_registration_pt registration);
-
-celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **response, int *responseLength);
-
-
-#endif //CELIX_EXPORT_REGISTRATION_DFI_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/include/import_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/include/import_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/private/include/import_registration_dfi.h
deleted file mode 100644
index aac4bc7..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/include/import_registration_dfi.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef CELIX_IMPORT_REGISTRATION_DFI_H
-#define CELIX_IMPORT_REGISTRATION_DFI_H
-
-#include "import_registration.h"
-#include "dfi_utils.h"
-
-#include <celix_errno.h>
-
-typedef void (*send_func_type)(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
-
-celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt description, const char *classObject, const char* serviceVersion,
-                                         import_registration_pt *import);
-celix_status_t importRegistration_close(import_registration_pt import);
-void importRegistration_destroy(import_registration_pt import);
-
-celix_status_t importRegistration_setSendFn(import_registration_pt reg,
-                                            send_func_type,
-                                            void *handle);
-celix_status_t importRegistration_start(import_registration_pt import);
-celix_status_t importRegistration_stop(import_registration_pt import);
-
-celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
-celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
-
-#endif //CELIX_IMPORT_REGISTRATION_DFI_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/include/remote_service_admin_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/include/remote_service_admin_dfi.h b/remote_services/remote_service_admin_dfi/rsa/private/include/remote_service_admin_dfi.h
deleted file mode 100644
index 8b282f1..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/include/remote_service_admin_dfi.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_http_impl.h
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-
-
-#include "bundle_context.h"
-#include "endpoint_description.h"
-
-//typedef struct remote_service_admin *remote_service_admin_pt;
-
-celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
-celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
-
-celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
-
-celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
-celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration);
-celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
-celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
-celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
-celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
-
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
-celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service);
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
-celix_status_t importReference_getImportedService(import_reference_pt reference);
-
-celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
-
-#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/dfi_utils.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/dfi_utils.c b/remote_services/remote_service_admin_dfi/rsa/private/src/dfi_utils.c
deleted file mode 100644
index 1b1eb36..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/dfi_utils.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include "dfi_utils.h"
-#include <stdlib.h>
-#include <unistd.h>
-
-static celix_status_t dfi_findFileForFramework(bundle_context_pt context, const char *fileName, FILE **out) {
-    celix_status_t  status;
-
-    char pwd[1024];
-    char path[1024];
-    const char *extPath = NULL;
-   
-    status = bundleContext_getProperty(context, "CELIX_FRAMEWORK_EXTENDER_PATH", &extPath);
-    if (status != CELIX_SUCCESS || extPath == NULL) {
-        getcwd(pwd, sizeof(pwd));
-        extPath = pwd;
-    }
-
-    snprintf(path, sizeof(path), "%s/%s", extPath, fileName);
-
-    if (status == CELIX_SUCCESS) {
-        FILE *df = fopen(path, "r");
-        if (df == NULL) {
-            status = CELIX_FILE_IO_EXCEPTION;
-        } else {
-            *out = df;
-        }
-    }
-
-    return status;
-}
-
-static celix_status_t dfi_findFileForBundle(bundle_pt bundle, const char *fileName, FILE **out) {
-    celix_status_t  status;
-
-    char *path = NULL;
-    char metaInfFileName[512];
-    snprintf(metaInfFileName, sizeof(metaInfFileName), "META-INF/descriptors/%s", fileName);
-
-    status = bundle_getEntry(bundle, fileName, &path);
-    
-    if (status != CELIX_SUCCESS || path == NULL) {
-        status = bundle_getEntry(bundle, metaInfFileName, &path);
-    }
-
-    if (status == CELIX_SUCCESS && path != NULL) {
-        FILE *df = fopen(path, "r");
-        if (df == NULL) {
-            status = CELIX_FILE_IO_EXCEPTION;
-        } else {
-            *out = df;
-        }
-
-    }
-
-    free(path);
-    return status;
-}
-
-celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out) {
-    celix_status_t  status;
-    char fileName[128];
-
-    snprintf(fileName, 128, "%s.descriptor", name);
-
-    long id;
-    status = bundle_getBundleId(bundle, &id);
-    
-    if (status == CELIX_SUCCESS) {
-        if (id == 0) {
-            //framework bundle
-            status = dfi_findFileForFramework(context, fileName, out);
-        } else {
-            //normal bundle
-            status = dfi_findFileForBundle(bundle, fileName, out);
-        }
-    }
-
-    return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
deleted file mode 100644
index b83b5a8..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <jansson.h>
-#include <dyn_interface.h>
-#include <json_serializer.h>
-#include <remote_constants.h>
-#include <remote_service_admin.h>
-#include <service_tracker_customizer.h>
-#include <service_tracker.h>
-#include <json_rpc.h>
-#include "constants.h"
-#include "export_registration_dfi.h"
-#include "dfi_utils.h"
-
-struct export_reference {
-    endpoint_description_pt endpoint; //owner
-    service_reference_pt reference;
-};
-
-struct export_registration {
-    bundle_context_pt  context;
-    struct export_reference exportReference;
-    char *servId;
-    dyn_interface_type *intf; //owner
-    service_tracker_pt tracker;
-
-    celix_thread_mutex_t mutex;
-    void *service; //protected by mutex
-
-    //TODO add tracker and lock
-    bool closed;
-};
-
-static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service);
-static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service);
-
-celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *out) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char *servId = NULL;
-    status = serviceReference_getProperty(reference, "service.id", &servId);
-    if (status != CELIX_SUCCESS) {
-        logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Cannot find service.id for ref");
-    }
-
-    export_registration_pt reg = NULL;
-    if (status == CELIX_SUCCESS) {
-        reg = calloc(1, sizeof(*reg));
-        if (reg == NULL) {
-            status = CELIX_ENOMEM;
-        }
-    }
-
-
-    if (status == CELIX_SUCCESS) {
-        reg->context = context;
-        reg->exportReference.endpoint = endpoint;
-        reg->exportReference.reference = reference;
-        reg->closed = false;
-
-        celixThreadMutex_create(&reg->mutex, NULL);
-    }
-
-    const char *exports = NULL;
-    CELIX_DO_IF(status, serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports));
-
-    bundle_pt bundle = NULL;
-    CELIX_DO_IF(status, serviceReference_getBundle(reference, &bundle));
-
-    FILE *descriptor = NULL;
-    if (status == CELIX_SUCCESS) {
-        status = dfi_findDescriptor(context, bundle, exports, &descriptor);
-    }
-
-    if (status != CELIX_SUCCESS || descriptor == NULL) {
-        status = CELIX_BUNDLE_EXCEPTION;
-        logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", exports);
-    }
-
-    if (status == CELIX_SUCCESS) {
-        int rc = dynInterface_parse(descriptor, &reg->intf);
-        fclose(descriptor);
-        if (rc != 0) {
-            status = CELIX_BUNDLE_EXCEPTION;
-            logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "RSA: Error parsing service descriptor.");
-        }
-        else{
-            /* Add the interface version as a property in the properties_map */
-            char* intfVersion = NULL;
-            dynInterface_getVersionString(reg->intf, &intfVersion);
-            const char *serviceVersion = properties_get(endpoint->properties,(char*) CELIX_FRAMEWORK_SERVICE_VERSION);
-            if(serviceVersion!=NULL){
-            	if(strcmp(serviceVersion,intfVersion)!=0){
-            		logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Service version (%s) and interface version from the descriptor (%s) are not the same!",serviceVersion,intfVersion);
-            	}
-            }
-            else{
-            	properties_set(endpoint->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION, intfVersion);
-            }
-        }
-    } 
-
-    if (status == CELIX_SUCCESS) {
-        service_tracker_customizer_pt cust = NULL;
-        status = serviceTrackerCustomizer_create(reg, NULL, (void *) exportRegistration_addServ, NULL,
-                                                 (void *) exportRegistration_removeServ, &cust);
-        if (status == CELIX_SUCCESS) {
-            char filter[32];
-            snprintf(filter, 32, "(service.id=%s)", servId);
-            status = serviceTracker_createWithFilter(reg->context, filter, cust, &reg->tracker);
-        }
-    }
-
-    if (status == CELIX_SUCCESS) {
-        *out = reg;
-    } else {
-        logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Error creating export registration");
-        exportRegistration_destroy(reg);
-    }
-
-    return status;
-}
-
-celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **responseOut, int *responseLength) {
-    int status = CELIX_SUCCESS;
-
-    //printf("calling for '%s'\n");
-
-    *responseLength = -1;
-    celixThreadMutex_lock(&export->mutex);
-    status = jsonRpc_call(export->intf, export->service, data, responseOut);
-    celixThreadMutex_unlock(&export->mutex);
-
-    return status;
-}
-
-void exportRegistration_destroy(export_registration_pt reg) {
-    if (reg != NULL) {
-        if (reg->intf != NULL) {
-            dyn_interface_type *intf = reg->intf;
-            reg->intf = NULL;
-            dynInterface_destroy(intf);
-        }
-
-        if (reg->exportReference.endpoint != NULL) {
-            endpoint_description_pt ep = reg->exportReference.endpoint;
-            reg->exportReference.endpoint = NULL;
-            endpointDescription_destroy(ep);
-        }
-        if (reg->tracker != NULL) {
-            serviceTracker_destroy(reg->tracker);
-        }
-        celixThreadMutex_destroy(&reg->mutex);
-
-        free(reg);
-    }
-}
-
-celix_status_t exportRegistration_start(export_registration_pt reg) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    serviceTracker_open(reg->tracker);
-    return status;
-}
-
-
-celix_status_t exportRegistration_stop(export_registration_pt reg) {
-    celix_status_t status = CELIX_SUCCESS;
-    if (status == CELIX_SUCCESS) {
-        status = bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
-        serviceTracker_close(reg->tracker);
-    }
-    return status;
-}
-
-static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service) {
-    celixThreadMutex_lock(&reg->mutex);
-    reg->service = service;
-    celixThreadMutex_unlock(&reg->mutex);
-}
-
-static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service) {
-    celixThreadMutex_lock(&reg->mutex);
-    if (reg->service == service) {
-        reg->service = NULL;
-    }
-    celixThreadMutex_unlock(&reg->mutex);
-}
-
-
-celix_status_t exportRegistration_close(export_registration_pt reg) {
-    celix_status_t status = CELIX_SUCCESS;
-    exportRegistration_stop(reg);
-    return status;
-}
-
-
-celix_status_t exportRegistration_getException(export_registration_pt registration) {
-    celix_status_t status = CELIX_SUCCESS;
-    //TODO
-    return status;
-}
-
-celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *out) {
-    celix_status_t status = CELIX_SUCCESS;
-    export_reference_pt ref = calloc(1, sizeof(*ref));
-    if (ref != NULL) {
-        ref->endpoint = registration->exportReference.endpoint;
-        ref->reference = registration->exportReference.reference;
-    } else {
-        status = CELIX_ENOMEM;
-    }
-
-    if (status == CELIX_SUCCESS) {
-        *out = ref;
-    }
-
-    return status;
-}
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
-    celix_status_t status = CELIX_SUCCESS;
-    *endpoint = reference->endpoint;
-    return status;
-}
-
-celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *ref) {
-    celix_status_t status = CELIX_SUCCESS;
-    *ref = reference->reference;
-    return status;
-}
-
-
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c
deleted file mode 100644
index 0b8dcf7..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <stdlib.h>
-#include <jansson.h>
-#include <json_rpc.h>
-#include <assert.h>
-#include "version.h"
-#include "json_serializer.h"
-#include "dyn_interface.h"
-#include "import_registration.h"
-#include "import_registration_dfi.h"
-
-struct import_registration {
-    bundle_context_pt context;
-    endpoint_description_pt  endpoint; //TODO owner? -> free when destroyed
-    const char *classObject; //NOTE owned by endpoint
-    version_pt version;
-
-    celix_thread_mutex_t mutex; //protects send & sendhandle
-    send_func_type send;
-    void *sendHandle;
-
-    service_factory_pt factory;
-    service_registration_pt factoryReg;
-
-    hash_map_pt proxies; //key -> bundle, value -> service_proxy
-    celix_thread_mutex_t proxiesMutex; //protects proxies
-};
-
-struct service_proxy {
-    dyn_interface_type *intf;
-    void *service;
-    size_t count;
-};
-
-static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle,
-                                              struct service_proxy **proxy);
-static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal);
-static void importRegistration_destroyProxy(struct service_proxy *proxy);
-static void importRegistration_clearProxies(import_registration_pt import);
-
-celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt endpoint, const char *classObject, const char* serviceVersion,
-                                         import_registration_pt *out) {
-    celix_status_t status = CELIX_SUCCESS;
-    import_registration_pt reg = calloc(1, sizeof(*reg));
-
-    if (reg != NULL) {
-        reg->factory = calloc(1, sizeof(*reg->factory));
-    }
-
-    if (reg != NULL && reg->factory != NULL) {
-        reg->context = context;
-        reg->endpoint = endpoint;
-        reg->classObject = classObject;
-        reg->proxies = hashMap_create(NULL, NULL, NULL, NULL);
-
-        celixThreadMutex_create(&reg->mutex, NULL);
-        celixThreadMutex_create(&reg->proxiesMutex, NULL);
-        status = version_createVersionFromString((char*)serviceVersion,&(reg->version));
-
-        reg->factory->handle = reg;
-        reg->factory->getService = (void *)importRegistration_getService;
-        reg->factory->ungetService = (void *)importRegistration_ungetService;
-    } else {
-        status = CELIX_ENOMEM;
-    }
-
-    if (status == CELIX_SUCCESS) {
-        //printf("IMPORT REGISTRATION IS %p\n", reg);
-        *out = reg;
-    }
-    else{
-    	importRegistration_destroy(reg);
-    }
-
-    return status;
-}
-
-
-celix_status_t importRegistration_setSendFn(import_registration_pt reg,
-                                            send_func_type send,
-                                            void *handle) {
-    celixThreadMutex_lock(&reg->mutex);
-    reg->send = send;
-    reg->sendHandle = handle;
-    celixThreadMutex_unlock(&reg->mutex);
-
-    return CELIX_SUCCESS;
-}
-
-static void importRegistration_clearProxies(import_registration_pt import) {
-    if (import != NULL) {
-        pthread_mutex_lock(&import->proxiesMutex);
-        if (import->proxies != NULL) {
-            hash_map_iterator_pt iter = hashMapIterator_create(import->proxies);
-            while (hashMapIterator_hasNext(iter)) {
-                hash_map_entry_pt  entry = hashMapIterator_nextEntry(iter);
-                struct service_proxy *proxy = hashMapEntry_getValue(entry);
-                importRegistration_destroyProxy(proxy);
-            }
-            hashMapIterator_destroy(iter);
-        }
-        pthread_mutex_unlock(&import->proxiesMutex);
-    }
-}
-
-void importRegistration_destroy(import_registration_pt import) {
-    if (import != NULL) {
-        if (import->proxies != NULL) {
-            hashMap_destroy(import->proxies, false, false);
-            import->proxies = NULL;
-        }
-
-        pthread_mutex_destroy(&import->mutex);
-        pthread_mutex_destroy(&import->proxiesMutex);
-
-        if (import->factory != NULL) {
-            free(import->factory);
-        }
-
-        if(import->version!=NULL){
-        	version_destroy(import->version);
-        }
-        free(import);
-    }
-}
-
-celix_status_t importRegistration_start(import_registration_pt import) {
-    celix_status_t  status = CELIX_SUCCESS;
-    if (import->factoryReg == NULL && import->factory != NULL) {
-        properties_pt props = NULL;
-        properties_copy(import->endpoint->properties, &props);
-        status = bundleContext_registerServiceFactory(import->context, (char *)import->classObject, import->factory, props, &import->factoryReg);
-    } else {
-        status = CELIX_ILLEGAL_STATE;
-    }
-    return status;
-}
-
-celix_status_t importRegistration_stop(import_registration_pt import) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    if (import->factoryReg != NULL) {
-        serviceRegistration_unregister(import->factoryReg);
-        import->factoryReg = NULL;
-    }
-
-    importRegistration_clearProxies(import);
-
-    return status;
-}
-
-
-celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
-    celix_status_t  status = CELIX_SUCCESS;
-
-    /*
-    module_pt module = NULL;
-    char *name = NULL;
-    bundle_getCurrentModule(bundle, &module);
-    module_getSymbolicName(module, &name);
-    printf("getting service for bundle '%s'\n", name);
-     */
-
-
-    pthread_mutex_lock(&import->proxiesMutex);
-    struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
-    if (proxy == NULL) {
-        status = importRegistration_createProxy(import, bundle, &proxy);
-        if (status == CELIX_SUCCESS) {
-            hashMap_put(import->proxies, bundle, proxy);
-        }
-    }
-
-    if (status == CELIX_SUCCESS) {
-        proxy->count += 1;
-        *out = proxy->service;
-    }
-    pthread_mutex_unlock(&import->proxiesMutex);
-
-    return status;
-}
-
-static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle, struct service_proxy **out) {
-    celix_status_t  status;
-    dyn_interface_type* intf = NULL;
-    FILE *descriptor = NULL;
-
-    status = dfi_findDescriptor(import->context, bundle, import->classObject, &descriptor);
-
-    if (status != CELIX_SUCCESS || descriptor == NULL) {
-        //TODO use log helper logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", import->classObject);
-        fprintf(stderr, "RSA_DFI: Cannot find/open descriptor for '%s'", import->classObject);
-        return CELIX_BUNDLE_EXCEPTION;
-    }
-
-    if (status == CELIX_SUCCESS) {
-        int rc = dynInterface_parse(descriptor, &intf);
-        fclose(descriptor);
-        if (rc != 0 || intf==NULL) {
-            return CELIX_BUNDLE_EXCEPTION;
-        }
-    }
-
-    /* Check if the imported service version is compatible with the one in the consumer descriptor */
-    version_pt consumerVersion = NULL;
-    bool isCompatible = false;
-    dynInterface_getVersion(intf,&consumerVersion);
-    version_isCompatible(consumerVersion,import->version,&isCompatible);
-
-    if(!isCompatible){
-    	char* cVerString = NULL;
-    	char* pVerString = NULL;
-    	version_toString(consumerVersion,&cVerString);
-    	version_toString(import->version,&pVerString);
-    	printf("Service version mismatch: consumer has %s, provider has %s. NOT creating proxy.\n",cVerString,pVerString);
-    	dynInterface_destroy(intf);
-    	free(cVerString);
-    	free(pVerString);
-    	status = CELIX_SERVICE_EXCEPTION;
-    }
-
-    struct service_proxy *proxy = NULL;
-    if (status == CELIX_SUCCESS) {
-        proxy = calloc(1, sizeof(*proxy));
-        if (proxy == NULL) {
-            status = CELIX_ENOMEM;
-        }
-    }
-
-    if (status == CELIX_SUCCESS) {
-    	proxy->intf = intf;
-        size_t count = dynInterface_nrOfMethods(proxy->intf);
-        proxy->service = calloc(1 + count, sizeof(void *));
-        if (proxy->service == NULL) {
-            status = CELIX_ENOMEM;
-        }
-    }
-
-    if (status == CELIX_SUCCESS) {
-        void **serv = proxy->service;
-        serv[0] = import;
-
-        struct methods_head *list = NULL;
-        dynInterface_methods(proxy->intf, &list);
-        struct method_entry *entry = NULL;
-        void (*fn)(void) = NULL;
-        int index = 0;
-        TAILQ_FOREACH(entry, list, entries) {
-            int rc = dynFunction_createClosure(entry->dynFunc, importRegistration_proxyFunc, entry, &fn);
-            serv[index + 1] = fn;
-            index += 1;
-
-            if (rc != 0) {
-                status = CELIX_BUNDLE_EXCEPTION;
-                break;
-            }
-        }
-    }
-
-    if (status == CELIX_SUCCESS) {
-        *out = proxy;
-    } else if (proxy != NULL) {
-        if (proxy->intf != NULL) {
-            dynInterface_destroy(proxy->intf);
-            proxy->intf = NULL;
-        }
-        free(proxy->service);
-        free(proxy);
-    }
-
-    return status;
-}
-
-static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal) {
-    int  status = CELIX_SUCCESS;
-    struct method_entry *entry = userData;
-    import_registration_pt import = *((void **)args[0]);
-
-    if (import == NULL || import->send == NULL) {
-        status = CELIX_ILLEGAL_ARGUMENT;
-    }
-
-
-    char *invokeRequest = NULL;
-    if (status == CELIX_SUCCESS) {
-        status = jsonRpc_prepareInvokeRequest(entry->dynFunc, entry->id, args, &invokeRequest);
-        //printf("Need to send following json '%s'\n", invokeRequest);
-    }
-
-
-    if (status == CELIX_SUCCESS) {
-        char *reply = NULL;
-        int rc = 0;
-        //printf("sending request\n");
-        celixThreadMutex_lock(&import->mutex);
-        if (import->send != NULL) {
-            import->send(import->sendHandle, import->endpoint, invokeRequest, &reply, &rc);
-        }
-        celixThreadMutex_unlock(&import->mutex);
-        //printf("request sended. got reply '%s' with status %i\n", reply, rc);
-
-        if (rc == 0) {
-            //fjprintf("Handling reply '%s'\n", reply);
-            status = jsonRpc_handleReply(entry->dynFunc, reply, args);
-        }
-
-        *(int *) returnVal = rc;
-
-        free(invokeRequest); //Allocated by json_dumps in jsonRpc_prepareInvokeRequest
-        free(reply); //Allocated by json_dumps in remoteServiceAdmin_send through curl call
-    }
-
-    if (status != CELIX_SUCCESS) {
-        //TODO log error
-    }
-}
-
-celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
-    celix_status_t  status = CELIX_SUCCESS;
-
-    assert(import != NULL);
-    assert(import->proxies != NULL);
-
-    pthread_mutex_lock(&import->proxiesMutex);
-
-    struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
-    if (proxy != NULL) {
-        if (*out == proxy->service) {
-            proxy->count -= 1;
-        } else {
-            status = CELIX_ILLEGAL_ARGUMENT;
-        }
-
-        if (proxy->count == 0) {
-            hashMap_remove(import->proxies, bundle);
-            importRegistration_destroyProxy(proxy);
-        }
-    }
-
-    pthread_mutex_unlock(&import->proxiesMutex);
-
-    return status;
-}
-
-static void importRegistration_destroyProxy(struct service_proxy *proxy) {
-    if (proxy != NULL) {
-        if (proxy->intf != NULL) {
-            dynInterface_destroy(proxy->intf);
-        }
-        if (proxy->service != NULL) {
-            free(proxy->service);
-        }
-        free(proxy);
-    }
-}
-
-
-celix_status_t importRegistration_close(import_registration_pt registration) {
-    celix_status_t status = CELIX_SUCCESS;
-    importRegistration_stop(registration);
-    return status;
-}
-
-celix_status_t importRegistration_getException(import_registration_pt registration) {
-    celix_status_t status = CELIX_SUCCESS;
-    //TODO
-    return status;
-}
-
-celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
-    celix_status_t status = CELIX_SUCCESS;
-    //TODO
-    return status;
-}
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-celix_status_t importReference_getImportedService(import_reference_pt reference) {
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_activator.c
deleted file mode 100644
index d4cc765..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_activator.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_activator.c
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <remote_service_admin.h>
-
-#include "remote_service_admin_dfi.h"
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-
-#include "export_registration_dfi.h"
-#include "import_registration_dfi.h"
-
-struct activator {
-	remote_service_admin_pt admin;
-	remote_service_admin_service_pt adminService;
-	service_registration_pt registration;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator;
-
-	activator = calloc(1, sizeof(*activator));
-	if (!activator) {
-		status = CELIX_ENOMEM;
-	} else {
-		activator->admin = NULL;
-		activator->registration = NULL;
-
-		*userData = activator;
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	remote_service_admin_service_pt remoteServiceAdmin = NULL;
-
-	status = remoteServiceAdmin_create(context, &activator->admin);
-	if (status == CELIX_SUCCESS) {
-		remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
-		if (!remoteServiceAdmin) {
-			status = CELIX_ENOMEM;
-		} else {
-			remoteServiceAdmin->admin = activator->admin;
-			remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
-
-			remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
-			remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
-			remoteServiceAdmin->importService = remoteServiceAdmin_importService;
-
-			remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
-			remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
-
-			remoteServiceAdmin->exportRegistration_close = remoteServiceAdmin_removeExportedService;
-			remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
-			remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
-
-			remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
-			remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
-
-			remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
-			remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
-			remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
-
-			status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
-			activator->adminService = remoteServiceAdmin;
-		}
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-    celix_status_t status = CELIX_SUCCESS;
-    struct activator *activator = userData;
-
-    serviceRegistration_unregister(activator->registration);
-    activator->registration = NULL;
-
-    remoteServiceAdmin_stop(activator->admin);
-    remoteServiceAdmin_destroy(&activator->admin);
-
-    free(activator->adminService);
-
-    return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	free(activator);
-
-	return status;
-}
-
-


[15/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c b/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c
new file mode 100644
index 0000000..94a8e11
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c
@@ -0,0 +1,457 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#include "constants.h"
+#include "celix_threads.h"
+#include "bundle_context.h"
+#include "array_list.h"
+#include "utils.h"
+#include "celix_errno.h"
+#include "filter.h"
+#include "service_reference.h"
+#include "service_registration.h"
+
+#include "publisher_endpoint_announce.h"
+#include "etcd_common.h"
+#include "etcd_watcher.h"
+#include "etcd_writer.h"
+#include "pubsub_endpoint.h"
+#include "pubsub_discovery_impl.h"
+
+/* Discovery activator functions */
+celix_status_t pubsub_discovery_create(bundle_context_pt context, pubsub_discovery_pt *ps_discovery) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*ps_discovery = calloc(1, sizeof(**ps_discovery));
+
+	if (*ps_discovery == NULL) {
+		status = CELIX_ENOMEM;
+	}
+	else{
+		(*ps_discovery)->context = context;
+		(*ps_discovery)->discoveredPubs = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+		(*ps_discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+		(*ps_discovery)->watchers = hashMap_create(utils_stringHash,NULL,utils_stringEquals, NULL);
+		celixThreadMutex_create(&(*ps_discovery)->listenerReferencesMutex, NULL);
+		celixThreadMutex_create(&(*ps_discovery)->discoveredPubsMutex, NULL);
+		celixThreadMutex_create(&(*ps_discovery)->watchersMutex, NULL);
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_discovery_destroy(pubsub_discovery_pt ps_discovery) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ps_discovery->discoveredPubsMutex);
+
+	hash_map_iterator_pt iter = hashMapIterator_create(ps_discovery->discoveredPubs);
+
+	while (hashMapIterator_hasNext(iter)) {
+		array_list_pt pubEP_list = (array_list_pt) hashMapIterator_nextValue(iter);
+
+		for(int i=0; i < arrayList_size(pubEP_list); i++) {
+			pubsubEndpoint_destroy(((pubsub_endpoint_pt)arrayList_get(pubEP_list,i)));
+		}
+		arrayList_destroy(pubEP_list);
+	}
+
+	hashMapIterator_destroy(iter);
+
+	hashMap_destroy(ps_discovery->discoveredPubs, true, false);
+	ps_discovery->discoveredPubs = NULL;
+
+	celixThreadMutex_unlock(&ps_discovery->discoveredPubsMutex);
+
+	celixThreadMutex_destroy(&ps_discovery->discoveredPubsMutex);
+
+
+	celixThreadMutex_lock(&ps_discovery->listenerReferencesMutex);
+
+	hashMap_destroy(ps_discovery->listenerReferences, false, false);
+	ps_discovery->listenerReferences = NULL;
+
+	celixThreadMutex_unlock(&ps_discovery->listenerReferencesMutex);
+
+	celixThreadMutex_destroy(&ps_discovery->listenerReferencesMutex);
+
+	free(ps_discovery);
+
+	return status;
+}
+
+celix_status_t pubsub_discovery_start(pubsub_discovery_pt ps_discovery) {
+    celix_status_t status = CELIX_SUCCESS;
+    status = etcdCommon_init(ps_discovery->context);
+    ps_discovery->writer = etcdWriter_create(ps_discovery);
+
+    return status;
+}
+
+celix_status_t pubsub_discovery_stop(pubsub_discovery_pt ps_discovery) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    const char* fwUUID = NULL;
+
+    bundleContext_getProperty(ps_discovery->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
+    if (fwUUID == NULL) {
+        printf("PSD: Cannot retrieve fwUUID.\n");
+        return CELIX_INVALID_BUNDLE_CONTEXT;
+    }
+
+    celixThreadMutex_lock(&ps_discovery->watchersMutex);
+
+    hash_map_iterator_pt iter = hashMapIterator_create(ps_discovery->watchers);
+    while (hashMapIterator_hasNext(iter)) {
+        struct watcher_info * wi = hashMapIterator_nextValue(iter);
+        etcdWatcher_stop(wi->watcher);
+    }
+    hashMapIterator_destroy(iter);
+
+    celixThreadMutex_lock(&ps_discovery->discoveredPubsMutex);
+
+    /* Unexport all publishers for the local framework, and also delete from ETCD publisher belonging to the local framework */
+
+    iter = hashMapIterator_create(ps_discovery->discoveredPubs);
+    while (hashMapIterator_hasNext(iter)) {
+        array_list_pt pubEP_list = (array_list_pt) hashMapIterator_nextValue(iter);
+
+        int i;
+        for (i = 0; i < arrayList_size(pubEP_list); i++) {
+            pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt) arrayList_get(pubEP_list, i);
+            if (strcmp(pubEP->frameworkUUID, fwUUID) == 0) {
+                etcdWriter_deletePublisherEndpoint(ps_discovery->writer, pubEP);
+            } else {
+                pubsub_discovery_informPublishersListeners(ps_discovery, pubEP, false);
+                arrayList_remove(pubEP_list, i);
+                pubsubEndpoint_destroy(pubEP);
+                i--;
+            }
+        }
+    }
+
+    hashMapIterator_destroy(iter);
+
+    celixThreadMutex_unlock(&ps_discovery->discoveredPubsMutex);
+    etcdWriter_destroy(ps_discovery->writer);
+
+    iter = hashMapIterator_create(ps_discovery->watchers);
+    while (hashMapIterator_hasNext(iter)) {
+        struct watcher_info * wi = hashMapIterator_nextValue(iter);
+        etcdWatcher_destroy(wi->watcher);
+    }
+    hashMapIterator_destroy(iter);
+    hashMap_destroy(ps_discovery->watchers, true, true);
+    celixThreadMutex_unlock(&ps_discovery->watchersMutex);
+    return status;
+}
+
+/* Functions called by the etcd_watcher */
+
+celix_status_t pubsub_discovery_addNode(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP) {
+	celix_status_t status = CELIX_SUCCESS;
+	bool inform=false;
+	celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+
+	char *pubs_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
+	array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pubs_key);
+	if(pubEP_list==NULL){
+		arrayList_create(&pubEP_list);
+		arrayList_add(pubEP_list,pubEP);
+		hashMap_put(pubsub_discovery->discoveredPubs,strdup(pubs_key),pubEP_list);
+		inform=true;
+	}
+	else{
+		int i;
+		bool found = false;
+		for(i=0;i<arrayList_size(pubEP_list) && !found;i++){
+			found = pubsubEndpoint_equals(pubEP,(pubsub_endpoint_pt)arrayList_get(pubEP_list,i));
+		}
+		if(found){
+			pubsubEndpoint_destroy(pubEP);
+		}
+		else{
+			arrayList_add(pubEP_list,pubEP);
+			inform=true;
+    	}
+	}
+	free(pubs_key);
+
+	celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+
+	if(inform){
+	    status = pubsub_discovery_informPublishersListeners(pubsub_discovery,pubEP,true);
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_discovery_removeNode(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP) {
+    celix_status_t status = CELIX_SUCCESS;
+    pubsub_endpoint_pt p = NULL;
+    bool found = false;
+
+    celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+    char *pubs_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
+    array_list_pt pubEP_list = (array_list_pt) hashMap_get(pubsub_discovery->discoveredPubs, pubs_key);
+    free(pubs_key);
+    if (pubEP_list == NULL) {
+        printf("PSD: Cannot find any registered publisher for topic %s. Something is not consistent.\n", pubEP->topic);
+        status = CELIX_ILLEGAL_STATE;
+    } else {
+        int i;
+
+        for (i = 0; !found && i < arrayList_size(pubEP_list); i++) {
+            p = arrayList_get(pubEP_list, i);
+            found = pubsubEndpoint_equals(pubEP, p);
+            if (found) {
+                arrayList_remove(pubEP_list, i);
+                pubsubEndpoint_destroy(p);
+            }
+        }
+    }
+
+    celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+    if (found) {
+        status = pubsub_discovery_informPublishersListeners(pubsub_discovery, pubEP, false);
+    }
+    pubsubEndpoint_destroy(pubEP);
+
+    return status;
+}
+
+/* Callback to the pubsub_topology_manager */
+celix_status_t pubsub_discovery_informPublishersListeners(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP, bool epAdded) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	// Inform listeners of new publisher endpoint
+	celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
+
+	if (pubsub_discovery->listenerReferences != NULL) {
+		hash_map_iterator_pt iter = hashMapIterator_create(pubsub_discovery->listenerReferences);
+		while (hashMapIterator_hasNext(iter)) {
+			service_reference_pt reference = hashMapIterator_nextKey(iter);
+
+			publisher_endpoint_announce_pt listener = NULL;
+
+			bundleContext_getService(pubsub_discovery->context, reference, (void**) &listener);
+            if (epAdded) {
+                listener->announcePublisher(listener->handle, pubEP);
+            } else {
+                listener->removePublisher(listener->handle, pubEP);
+            }
+            bundleContext_ungetService(pubsub_discovery->context, reference, NULL);
+		}
+		hashMapIterator_destroy(iter);
+	}
+
+	celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
+
+	return status;
+}
+
+
+/* Service's functions implementation */
+celix_status_t pubsub_discovery_announcePublisher(void *handle, pubsub_endpoint_pt pubEP) {
+	celix_status_t status = CELIX_SUCCESS;
+	printf("pubsub_discovery_announcePublisher : %s / %s\n", pubEP->topic, pubEP->endpoint);
+	pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
+
+	celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+
+	char *pub_key = createScopeTopicKey(pubEP->scope,pubEP->topic);
+	array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pub_key);
+
+	if(pubEP_list==NULL){
+		arrayList_create(&pubEP_list);
+		hashMap_put(pubsub_discovery->discoveredPubs,strdup(pub_key),pubEP_list);
+	}
+	free(pub_key);
+	pubsub_endpoint_pt p = NULL;
+	pubsubEndpoint_clone(pubEP, &p);
+
+	arrayList_add(pubEP_list,p);
+
+	status = etcdWriter_addPublisherEndpoint(pubsub_discovery->writer,p,true);
+
+	celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+
+	return status;
+}
+
+celix_status_t pubsub_discovery_removePublisher(void *handle, pubsub_endpoint_pt pubEP) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
+
+	celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+
+	char *pub_key = createScopeTopicKey(pubEP->scope,pubEP->topic);
+	array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pub_key);
+	free(pub_key);
+	if(pubEP_list==NULL){
+		printf("PSD: Cannot find any registered publisher for topic %s. Something is not consistent.\n",pubEP->topic);
+		status = CELIX_ILLEGAL_STATE;
+	}
+	else{
+
+		int i;
+		bool found = false;
+		pubsub_endpoint_pt p = NULL;
+
+		for(i=0;!found && i<arrayList_size(pubEP_list);i++){
+			p = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
+			found = pubsubEndpoint_equals(pubEP,p);
+		}
+
+		if(!found){
+			printf("PSD: Trying to remove a not existing endpoint. Something is not consistent.\n");
+			status = CELIX_ILLEGAL_STATE;
+		}
+		else{
+
+			arrayList_removeElement(pubEP_list,p);
+
+			status = etcdWriter_deletePublisherEndpoint(pubsub_discovery->writer,p);
+
+			pubsubEndpoint_destroy(p);
+		}
+	}
+
+	celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+
+	return status;
+}
+
+celix_status_t pubsub_discovery_interestedInTopic(void *handle, const char* scope, const char* topic) {
+    pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
+
+    char *scope_topic_key = createScopeTopicKey(scope, topic);
+    celixThreadMutex_lock(&pubsub_discovery->watchersMutex);
+    struct watcher_info * wi = hashMap_get(pubsub_discovery->watchers, scope_topic_key);
+    if(wi) {
+        wi->nr_references++;
+        free(scope_topic_key);
+    } else {
+        wi = calloc(1, sizeof(*wi));
+        etcdWatcher_create(pubsub_discovery, pubsub_discovery->context, scope, topic, &wi->watcher);
+        wi->nr_references = 1;
+        hashMap_put(pubsub_discovery->watchers, scope_topic_key, wi);
+    }
+
+    celixThreadMutex_unlock(&pubsub_discovery->watchersMutex);
+
+    return CELIX_SUCCESS;
+}
+
+celix_status_t pubsub_discovery_uninterestedInTopic(void *handle, const char* scope, const char* topic) {
+    pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
+
+    char *scope_topic_key = createScopeTopicKey(scope, topic);
+    celixThreadMutex_lock(&pubsub_discovery->watchersMutex);
+
+    hash_map_entry_pt entry =  hashMap_getEntry(pubsub_discovery->watchers, scope_topic_key);
+    if(entry) {
+        struct watcher_info * wi = hashMapEntry_getValue(entry);
+        wi->nr_references--;
+        if(wi->nr_references == 0) {
+            char *key = hashMapEntry_getKey(entry);
+            hashMap_remove(pubsub_discovery->watchers, scope_topic_key);
+            free(key);
+            free(scope_topic_key);
+            etcdWatcher_stop(wi->watcher);
+            etcdWatcher_destroy(wi->watcher);
+            free(wi);
+        }
+    } else {
+        fprintf(stderr, "[DISC] Inconsistency error: Removing unknown topic %s\n", topic);
+    }
+    celixThreadMutex_unlock(&pubsub_discovery->watchersMutex);
+    return CELIX_SUCCESS;
+}
+
+/* pubsub_topology_manager tracker callbacks */
+
+celix_status_t pubsub_discovery_tmPublisherAnnounceAdded(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt)handle;
+	publisher_endpoint_announce_pt listener = (publisher_endpoint_announce_pt)service;
+
+	celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+	celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
+
+	/* Notify the PSTM about discovered publisher endpoints */
+	hash_map_iterator_pt iter = hashMapIterator_create(pubsub_discovery->discoveredPubs);
+	while(hashMapIterator_hasNext(iter)){
+		array_list_pt pubEP_list = (array_list_pt)hashMapIterator_nextValue(iter);
+		int i;
+		for(i=0;i<arrayList_size(pubEP_list);i++){
+			pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
+			status += listener->announcePublisher(listener->handle, pubEP);
+		}
+	}
+
+	hashMapIterator_destroy(iter);
+
+	hashMap_put(pubsub_discovery->listenerReferences, reference, NULL);
+
+	celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
+	celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+
+	printf("PSD: pubsub_tm_announce_publisher added.\n");
+
+	return status;
+}
+
+celix_status_t pubsub_discovery_tmPublisherAnnounceModified(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	status = pubsub_discovery_tmPublisherAnnounceRemoved(handle, reference, service);
+	if (status == CELIX_SUCCESS) {
+		status = pubsub_discovery_tmPublisherAnnounceAdded(handle, reference, service);
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_discovery_tmPublisherAnnounceRemoved(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	pubsub_discovery_pt pubsub_discovery = handle;
+
+	celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
+
+	if (pubsub_discovery->listenerReferences != NULL) {
+		if (hashMap_remove(pubsub_discovery->listenerReferences, reference)) {
+			printf("PSD: pubsub_tm_announce_publisher removed.\n");
+		}
+	}
+	celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
+
+	return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h b/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h
new file mode 100644
index 0000000..676a6ab
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h
@@ -0,0 +1,72 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef PUBSUB_DISCOVERY_IMPL_H_
+#define PUBSUB_DISCOVERY_IMPL_H_
+
+#include "bundle_context.h"
+#include "service_reference.h"
+
+#include "etcd_watcher.h"
+#include "etcd_writer.h"
+#include "pubsub_endpoint.h"
+
+#define FREE_MEM(ptr) if(ptr) {free(ptr); ptr = NULL;}
+
+struct watcher_info {
+    etcd_watcher_pt watcher;
+    int nr_references;
+};
+
+struct pubsub_discovery {
+	bundle_context_pt context;
+
+	celix_thread_mutex_t discoveredPubsMutex;
+	hash_map_pt discoveredPubs; //<topic,List<pubsub_endpoint_pt>>
+
+	celix_thread_mutex_t listenerReferencesMutex;
+	hash_map_pt listenerReferences; //key=serviceReference, value=nop
+
+	celix_thread_mutex_t watchersMutex;
+	hash_map_pt watchers; //key = topicname, value = struct watcher_info
+
+	etcd_writer_pt writer;
+};
+
+
+celix_status_t pubsub_discovery_create(bundle_context_pt context, pubsub_discovery_pt* node_discovery);
+celix_status_t pubsub_discovery_destroy(pubsub_discovery_pt node_discovery);
+celix_status_t pubsub_discovery_start(pubsub_discovery_pt node_discovery);
+celix_status_t pubsub_discovery_stop(pubsub_discovery_pt node_discovery);
+
+celix_status_t pubsub_discovery_addNode(pubsub_discovery_pt node_discovery, pubsub_endpoint_pt pubEP);
+celix_status_t pubsub_discovery_removeNode(pubsub_discovery_pt node_discovery, pubsub_endpoint_pt pubEP);
+
+celix_status_t pubsub_discovery_tmPublisherAnnounceAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t pubsub_discovery_tmPublisherAnnounceModified(void * handle, service_reference_pt reference, void * service);
+celix_status_t pubsub_discovery_tmPublisherAnnounceRemoved(void * handle, service_reference_pt reference, void * service);
+
+celix_status_t pubsub_discovery_announcePublisher(void *handle, pubsub_endpoint_pt pubEP);
+celix_status_t pubsub_discovery_removePublisher(void *handle, pubsub_endpoint_pt pubEP);
+celix_status_t pubsub_discovery_interestedInTopic(void *handle, const char* scope, const char* topic);
+celix_status_t pubsub_discovery_uninterestedInTopic(void *handle, const char* scope, const char* topic);
+
+celix_status_t pubsub_discovery_informPublishersListeners(pubsub_discovery_pt discovery, pubsub_endpoint_pt endpoint, bool endpointAdded);
+
+#endif /* PUBSUB_DISCOVERY_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/CMakeLists.txt b/pubsub/pubsub_serializer_json/CMakeLists.txt
index 147873a..b86f30e 100644
--- a/pubsub/pubsub_serializer_json/CMakeLists.txt
+++ b/pubsub/pubsub_serializer_json/CMakeLists.txt
@@ -17,27 +17,23 @@
 
 find_package(Jansson REQUIRED)
 
-include_directories("private/include")
-include_directories("public/include")
-include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/dfi/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("${JANSSON_INCLUDE_DIR}")
 
 add_bundle(org.apache.celix.pubsub_serializer.PubSubSerializerJson
     BUNDLE_SYMBOLICNAME "apache_celix_pubsub_serializer_json"
     VERSION "1.0.0"
     SOURCES
-    	private/src/ps_activator.c
-    	private/src/pubsub_serializer_impl.c
-	   ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+		src/ps_activator.c
+		src/pubsub_serializer_impl.c
     	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
 )
 
+target_include_directories(org.apache.celix.pubsub_serializer.PubSubSerializerJson PRIVATE
+	src
+	${JANSSON_INCLUDE_DIR}
+)
+
 set_target_properties(org.apache.celix.pubsub_serializer.PubSubSerializerJson PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(org.apache.celix.pubsub_serializer.PubSubSerializerJson celix_framework celix_utils celix_dfi ${JANSSON_LIBRARIES})
+target_link_libraries(org.apache.celix.pubsub_serializer.PubSubSerializerJson PRIVATE Celix::framework Celix::dfi ${JANSSON_LIBRARIES} Celix::log_helper)
 
 install_bundle(org.apache.celix.pubsub_serializer.PubSubSerializerJson)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/private/include/pubsub_serializer_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/private/include/pubsub_serializer_impl.h b/pubsub/pubsub_serializer_json/private/include/pubsub_serializer_impl.h
deleted file mode 100644
index c36f20e..0000000
--- a/pubsub/pubsub_serializer_json/private/include/pubsub_serializer_impl.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * pubsub_serializer_impl.h
- *
- *  \date       Mar 24, 2017
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_SERIALIZER_JSON_H_
-#define PUBSUB_SERIALIZER_JSON_H_
-
-#include "dyn_common.h"
-#include "dyn_type.h"
-#include "dyn_message.h"
-#include "log_helper.h"
-
-#include "pubsub_serializer.h"
-
-#define PUBSUB_SERIALIZER_TYPE	"json"
-
-typedef struct pubsub_serializer {
-	bundle_context_pt bundle_context;
-	log_helper_pt loghelper;
-} pubsub_serializer_t;
-
-celix_status_t pubsubSerializer_create(bundle_context_pt context, pubsub_serializer_t* *serializer);
-celix_status_t pubsubSerializer_destroy(pubsub_serializer_t* serializer);
-
-celix_status_t pubsubSerializer_createSerializerMap(pubsub_serializer_t* serializer, bundle_pt bundle, hash_map_pt* serializerMap);
-celix_status_t pubsubSerializer_destroySerializerMap(pubsub_serializer_t*, hash_map_pt serializerMap);
-
-/* Start of serializer specific functions */
-celix_status_t pubsubMsgSerializer_serialize(pubsub_msg_serializer_t* msgSerializer, const void* msg, void** out, size_t *outLen);
-celix_status_t pubsubMsgSerializer_deserialize(pubsub_msg_serializer_t* msgSerializer, const void* input, size_t inputLen, void **out);
-void pubsubMsgSerializer_freeMsg(pubsub_msg_serializer_t* msgSerializer, void *msg);
-
-#endif /* PUBSUB_SERIALIZER_JSON_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/private/src/ps_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/private/src/ps_activator.c b/pubsub/pubsub_serializer_json/private/src/ps_activator.c
deleted file mode 100644
index fec5892..0000000
--- a/pubsub/pubsub_serializer_json/private/src/ps_activator.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * ps_activator.c
- *
- *  \date       Mar 24, 2017
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-
-#include "pubsub_serializer_impl.h"
-
-struct activator {
-	pubsub_serializer_t* serializer;
-	pubsub_serializer_service_t* serializerService;
-	service_registration_pt registration;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator;
-
-	activator = calloc(1, sizeof(*activator));
-	if (!activator) {
-		status = CELIX_ENOMEM;
-	}
-	else{
-		*userData = activator;
-		status = pubsubSerializer_create(context, &(activator->serializer));
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	pubsub_serializer_service_t* pubsubSerializerSvc = calloc(1, sizeof(*pubsubSerializerSvc));
-
-	if (!pubsubSerializerSvc) {
-		status = CELIX_ENOMEM;
-	}
-	else{
-		pubsubSerializerSvc->handle = activator->serializer;
-
-		pubsubSerializerSvc->createSerializerMap = (void*)pubsubSerializer_createSerializerMap;
-		pubsubSerializerSvc->destroySerializerMap = (void*)pubsubSerializer_destroySerializerMap;
-		activator->serializerService = pubsubSerializerSvc;
-
-		/* Set serializer type */
-		properties_pt props = properties_create();
-		properties_set(props,PUBSUB_SERIALIZER_TYPE_KEY,PUBSUB_SERIALIZER_TYPE);
-
-		status = bundleContext_registerService(context, PUBSUB_SERIALIZER_SERVICE, pubsubSerializerSvc, props, &activator->registration);
-
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	serviceRegistration_unregister(activator->registration);
-	activator->registration = NULL;
-
-	free(activator->serializerService);
-	activator->serializerService = NULL;
-
-	return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	pubsubSerializer_destroy(activator->serializer);
-	activator->serializer = NULL;
-
-	free(activator);
-
-	return status;
-}
-
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/private/src/pubsub_serializer_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/private/src/pubsub_serializer_impl.c b/pubsub/pubsub_serializer_json/private/src/pubsub_serializer_impl.c
deleted file mode 100644
index 685d499..0000000
--- a/pubsub/pubsub_serializer_json/private/src/pubsub_serializer_impl.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * pubsub_serializer_impl.c
- *
- *  \date       Mar 24, 2017
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <inttypes.h>
-
-#include "utils.h"
-#include "hash_map.h"
-#include "bundle_context.h"
-
-#include "log_helper.h"
-
-#include "json_serializer.h"
-
-#include "pubsub_serializer_impl.h"
-
-#define SYSTEM_BUNDLE_ARCHIVE_PATH 		"CELIX_FRAMEWORK_EXTENDER_PATH"
-#define MAX_PATH_LEN    1024
-
-static char* pubsubSerializer_getMsgDescriptionDir(bundle_pt bundle);
-static void pubsubSerializer_addMsgSerializerFromBundle(const char *root, bundle_pt bundle, hash_map_pt msgTypesMap);
-static void pubsubSerializer_fillMsgSerializerMap(hash_map_pt msgTypesMap,bundle_pt bundle);
-
-celix_status_t pubsubSerializer_create(bundle_context_pt context, pubsub_serializer_t** serializer) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*serializer = calloc(1, sizeof(**serializer));
-
-	if (!*serializer) {
-		status = CELIX_ENOMEM;
-	}
-	else{
-
-		(*serializer)->bundle_context= context;
-
-		if (logHelper_create(context, &(*serializer)->loghelper) == CELIX_SUCCESS) {
-			logHelper_start((*serializer)->loghelper);
-		}
-
-	}
-
-	return status;
-}
-
-celix_status_t pubsubSerializer_destroy(pubsub_serializer_t* serializer) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	logHelper_stop(serializer->loghelper);
-	logHelper_destroy(&serializer->loghelper);
-
-	free(serializer);
-
-	return status;
-}
-
-celix_status_t pubsubSerializer_createSerializerMap(pubsub_serializer_t* serializer, bundle_pt bundle, hash_map_pt* serializerMap) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL);
-
-	if (map != NULL) {
-		pubsubSerializer_fillMsgSerializerMap(map, bundle);
-	} else {
-		logHelper_log(serializer->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot allocate memory for msg map");
-		status = CELIX_ENOMEM;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		*serializerMap = map;
-	}
-	return status;
-}
-
-celix_status_t pubsubSerializer_destroySerializerMap(pubsub_serializer_t* serializer, hash_map_pt serializerMap) {
-	celix_status_t status = CELIX_SUCCESS;
-	if (serializerMap == NULL) {
-		return CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	hash_map_iterator_t iter = hashMapIterator_construct(serializerMap);
-	while (hashMapIterator_hasNext(&iter)) {
-		pubsub_msg_serializer_t* msgSerializer = hashMapIterator_nextValue(&iter);
-		dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
-		dynMessage_destroy(dynMsg); //note msgSer->name and msgSer->version owned by dynType
-		free(msgSerializer); //also contains the service struct.
-	}
-
-	hashMap_destroy(serializerMap, false, false);
-
-	return status;
-}
-
-
-celix_status_t pubsubMsgSerializer_serialize(pubsub_msg_serializer_t* msgSerializer, const void* msg, void** out, size_t *outLen) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	char *jsonOutput = NULL;
-	dyn_type* dynType = NULL;
-	dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
-	dynMessage_getMessageType(dynMsg, &dynType);
-
-	if (jsonSerializer_serialize(dynType, msg, &jsonOutput) != 0){
-		status = CELIX_BUNDLE_EXCEPTION;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		*out = jsonOutput;
-		*outLen = strlen(jsonOutput) + 1;
-	}
-
-	return status;
-}
-
-celix_status_t pubsubMsgSerializer_deserialize(pubsub_msg_serializer_t* msgSerializer, const void* input, size_t inputLen, void **out) {
-
-	celix_status_t status = CELIX_SUCCESS;
-	void *msg = NULL;
-	dyn_type* dynType = NULL;
-	dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
-	dynMessage_getMessageType(dynMsg, &dynType);
-
-	if (jsonSerializer_deserialize(dynType, (const char*)input, &msg) != 0) {
-		status = CELIX_BUNDLE_EXCEPTION;
-	}
-	else{
-		*out = msg;
-	}
-
-	return status;
-}
-
-void pubsubMsgSerializer_freeMsg(pubsub_msg_serializer_t* msgSerializer, void *msg) {
-	dyn_type* dynType = NULL;
-	dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
-	dynMessage_getMessageType(dynMsg, &dynType);
-	if (dynType != NULL) {
-		dynType_free(dynType, msg);
-	}
-}
-
-
-static void pubsubSerializer_fillMsgSerializerMap(hash_map_pt msgSerializers, bundle_pt bundle) {
-	char* root = NULL;
-	char* metaInfPath = NULL;
-
-	root = pubsubSerializer_getMsgDescriptionDir(bundle);
-
-	if(root != NULL){
-		asprintf(&metaInfPath, "%s/META-INF/descriptors", root);
-
-		pubsubSerializer_addMsgSerializerFromBundle(root, bundle, msgSerializers);
-		pubsubSerializer_addMsgSerializerFromBundle(metaInfPath, bundle, msgSerializers);
-
-		free(metaInfPath);
-		free(root);
-	}
-}
-
-static char* pubsubSerializer_getMsgDescriptionDir(bundle_pt bundle)
-{
-	char *root = NULL;
-
-	bool isSystemBundle = false;
-	bundle_isSystemBundle(bundle, &isSystemBundle);
-
-	if(isSystemBundle == true) {
-		bundle_context_pt context;
-		bundle_getContext(bundle, &context);
-
-		const char *prop = NULL;
-
-		bundleContext_getProperty(context, SYSTEM_BUNDLE_ARCHIVE_PATH, &prop);
-
-		if(prop != NULL) {
-			root = strdup(prop);
-		} else {
-			root = getcwd(NULL, 0);
-		}
-	} else {
-		bundle_getEntry(bundle, ".", &root);
-	}
-
-	return root;
-}
-
-
-static void pubsubSerializer_addMsgSerializerFromBundle(const char *root, bundle_pt bundle, hash_map_pt msgSerializers)
-{
-	char path[MAX_PATH_LEN];
-	struct dirent *entry = NULL;
-	DIR *dir = opendir(root);
-
-	if(dir) {
-		entry = readdir(dir);
-	}
-
-	while (entry != NULL) {
-
-		if (strstr(entry->d_name, ".descriptor") != NULL) {
-
-			printf("DMU: Parsing entry '%s'\n", entry->d_name);
-
-			snprintf(path, MAX_PATH_LEN, "%s/%s", root, entry->d_name);
-			FILE *stream = fopen(path,"r");
-
-			if (stream != NULL){
-				dyn_message_type* msgType = NULL;
-
-				int rc = dynMessage_parse(stream, &msgType);
-				if (rc == 0 && msgType != NULL) {
-
-					char* msgName = NULL;
-					rc += dynMessage_getName(msgType,&msgName);
-
-					version_pt msgVersion = NULL;
-					rc += dynMessage_getVersion(msgType, &msgVersion);
-
-					if(rc == 0 && msgName != NULL && msgVersion != NULL){
-
-						unsigned int msgId = utils_stringHash(msgName);
-
-						pubsub_msg_serializer_t *msgSerializer = calloc(1,sizeof(pubsub_msg_serializer_t));
-
-						msgSerializer->handle = msgType;
-						msgSerializer->msgId = msgId;
-						msgSerializer->msgName = msgName;
-						msgSerializer->msgVersion = msgVersion;
-						msgSerializer->serialize = (void*) pubsubMsgSerializer_serialize;
-						msgSerializer->deserialize = (void*) pubsubMsgSerializer_deserialize;
-						msgSerializer->freeMsg = (void*) pubsubMsgSerializer_freeMsg;
-
-						bool clash = hashMap_containsKey(msgSerializers, (void*)(uintptr_t)msgId);
-						if (clash){
-							printf("Cannot add msg %s. clash in msg id %d!!\n", msgName, msgId);
-							free(msgSerializer);
-							dynMessage_destroy(msgType);
-						}
-						else if (msgId != 0){
-							printf("Adding %u : %s\n", msgId, msgName);
-							hashMap_put(msgSerializers, (void*)(uintptr_t)msgId, msgSerializer);
-						}
-						else{
-							printf("Error creating msg serializer\n");
-							free(msgSerializer);
-							dynMessage_destroy(msgType);
-						}
-
-					}
-					else{
-						printf("Cannot retrieve name and/or version from msg\n");
-					}
-
-				} else{
-					printf("DMU: cannot parse message from descriptor %s\n.",path);
-				}
-				fclose(stream);
-			}else{
-				printf("DMU: cannot open descriptor file %s\n.",path);
-			}
-
-		}
-		entry = readdir(dir);
-	}
-
-	if(dir) {
-		closedir(dir);
-	}
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/src/ps_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/src/ps_activator.c b/pubsub/pubsub_serializer_json/src/ps_activator.c
new file mode 100644
index 0000000..fec5892
--- /dev/null
+++ b/pubsub/pubsub_serializer_json/src/ps_activator.c
@@ -0,0 +1,107 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * ps_activator.c
+ *
+ *  \date       Mar 24, 2017
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+
+#include "pubsub_serializer_impl.h"
+
+struct activator {
+	pubsub_serializer_t* serializer;
+	pubsub_serializer_service_t* serializerService;
+	service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator;
+
+	activator = calloc(1, sizeof(*activator));
+	if (!activator) {
+		status = CELIX_ENOMEM;
+	}
+	else{
+		*userData = activator;
+		status = pubsubSerializer_create(context, &(activator->serializer));
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	pubsub_serializer_service_t* pubsubSerializerSvc = calloc(1, sizeof(*pubsubSerializerSvc));
+
+	if (!pubsubSerializerSvc) {
+		status = CELIX_ENOMEM;
+	}
+	else{
+		pubsubSerializerSvc->handle = activator->serializer;
+
+		pubsubSerializerSvc->createSerializerMap = (void*)pubsubSerializer_createSerializerMap;
+		pubsubSerializerSvc->destroySerializerMap = (void*)pubsubSerializer_destroySerializerMap;
+		activator->serializerService = pubsubSerializerSvc;
+
+		/* Set serializer type */
+		properties_pt props = properties_create();
+		properties_set(props,PUBSUB_SERIALIZER_TYPE_KEY,PUBSUB_SERIALIZER_TYPE);
+
+		status = bundleContext_registerService(context, PUBSUB_SERIALIZER_SERVICE, pubsubSerializerSvc, props, &activator->registration);
+
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	serviceRegistration_unregister(activator->registration);
+	activator->registration = NULL;
+
+	free(activator->serializerService);
+	activator->serializerService = NULL;
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	pubsubSerializer_destroy(activator->serializer);
+	activator->serializer = NULL;
+
+	free(activator);
+
+	return status;
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.c b/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.c
new file mode 100644
index 0000000..685d499
--- /dev/null
+++ b/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.c
@@ -0,0 +1,295 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * pubsub_serializer_impl.c
+ *
+ *  \date       Mar 24, 2017
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <inttypes.h>
+
+#include "utils.h"
+#include "hash_map.h"
+#include "bundle_context.h"
+
+#include "log_helper.h"
+
+#include "json_serializer.h"
+
+#include "pubsub_serializer_impl.h"
+
+#define SYSTEM_BUNDLE_ARCHIVE_PATH 		"CELIX_FRAMEWORK_EXTENDER_PATH"
+#define MAX_PATH_LEN    1024
+
+static char* pubsubSerializer_getMsgDescriptionDir(bundle_pt bundle);
+static void pubsubSerializer_addMsgSerializerFromBundle(const char *root, bundle_pt bundle, hash_map_pt msgTypesMap);
+static void pubsubSerializer_fillMsgSerializerMap(hash_map_pt msgTypesMap,bundle_pt bundle);
+
+celix_status_t pubsubSerializer_create(bundle_context_pt context, pubsub_serializer_t** serializer) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*serializer = calloc(1, sizeof(**serializer));
+
+	if (!*serializer) {
+		status = CELIX_ENOMEM;
+	}
+	else{
+
+		(*serializer)->bundle_context= context;
+
+		if (logHelper_create(context, &(*serializer)->loghelper) == CELIX_SUCCESS) {
+			logHelper_start((*serializer)->loghelper);
+		}
+
+	}
+
+	return status;
+}
+
+celix_status_t pubsubSerializer_destroy(pubsub_serializer_t* serializer) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	logHelper_stop(serializer->loghelper);
+	logHelper_destroy(&serializer->loghelper);
+
+	free(serializer);
+
+	return status;
+}
+
+celix_status_t pubsubSerializer_createSerializerMap(pubsub_serializer_t* serializer, bundle_pt bundle, hash_map_pt* serializerMap) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL);
+
+	if (map != NULL) {
+		pubsubSerializer_fillMsgSerializerMap(map, bundle);
+	} else {
+		logHelper_log(serializer->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot allocate memory for msg map");
+		status = CELIX_ENOMEM;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		*serializerMap = map;
+	}
+	return status;
+}
+
+celix_status_t pubsubSerializer_destroySerializerMap(pubsub_serializer_t* serializer, hash_map_pt serializerMap) {
+	celix_status_t status = CELIX_SUCCESS;
+	if (serializerMap == NULL) {
+		return CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	hash_map_iterator_t iter = hashMapIterator_construct(serializerMap);
+	while (hashMapIterator_hasNext(&iter)) {
+		pubsub_msg_serializer_t* msgSerializer = hashMapIterator_nextValue(&iter);
+		dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
+		dynMessage_destroy(dynMsg); //note msgSer->name and msgSer->version owned by dynType
+		free(msgSerializer); //also contains the service struct.
+	}
+
+	hashMap_destroy(serializerMap, false, false);
+
+	return status;
+}
+
+
+celix_status_t pubsubMsgSerializer_serialize(pubsub_msg_serializer_t* msgSerializer, const void* msg, void** out, size_t *outLen) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	char *jsonOutput = NULL;
+	dyn_type* dynType = NULL;
+	dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
+	dynMessage_getMessageType(dynMsg, &dynType);
+
+	if (jsonSerializer_serialize(dynType, msg, &jsonOutput) != 0){
+		status = CELIX_BUNDLE_EXCEPTION;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		*out = jsonOutput;
+		*outLen = strlen(jsonOutput) + 1;
+	}
+
+	return status;
+}
+
+celix_status_t pubsubMsgSerializer_deserialize(pubsub_msg_serializer_t* msgSerializer, const void* input, size_t inputLen, void **out) {
+
+	celix_status_t status = CELIX_SUCCESS;
+	void *msg = NULL;
+	dyn_type* dynType = NULL;
+	dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
+	dynMessage_getMessageType(dynMsg, &dynType);
+
+	if (jsonSerializer_deserialize(dynType, (const char*)input, &msg) != 0) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	}
+	else{
+		*out = msg;
+	}
+
+	return status;
+}
+
+void pubsubMsgSerializer_freeMsg(pubsub_msg_serializer_t* msgSerializer, void *msg) {
+	dyn_type* dynType = NULL;
+	dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
+	dynMessage_getMessageType(dynMsg, &dynType);
+	if (dynType != NULL) {
+		dynType_free(dynType, msg);
+	}
+}
+
+
+static void pubsubSerializer_fillMsgSerializerMap(hash_map_pt msgSerializers, bundle_pt bundle) {
+	char* root = NULL;
+	char* metaInfPath = NULL;
+
+	root = pubsubSerializer_getMsgDescriptionDir(bundle);
+
+	if(root != NULL){
+		asprintf(&metaInfPath, "%s/META-INF/descriptors", root);
+
+		pubsubSerializer_addMsgSerializerFromBundle(root, bundle, msgSerializers);
+		pubsubSerializer_addMsgSerializerFromBundle(metaInfPath, bundle, msgSerializers);
+
+		free(metaInfPath);
+		free(root);
+	}
+}
+
+static char* pubsubSerializer_getMsgDescriptionDir(bundle_pt bundle)
+{
+	char *root = NULL;
+
+	bool isSystemBundle = false;
+	bundle_isSystemBundle(bundle, &isSystemBundle);
+
+	if(isSystemBundle == true) {
+		bundle_context_pt context;
+		bundle_getContext(bundle, &context);
+
+		const char *prop = NULL;
+
+		bundleContext_getProperty(context, SYSTEM_BUNDLE_ARCHIVE_PATH, &prop);
+
+		if(prop != NULL) {
+			root = strdup(prop);
+		} else {
+			root = getcwd(NULL, 0);
+		}
+	} else {
+		bundle_getEntry(bundle, ".", &root);
+	}
+
+	return root;
+}
+
+
+static void pubsubSerializer_addMsgSerializerFromBundle(const char *root, bundle_pt bundle, hash_map_pt msgSerializers)
+{
+	char path[MAX_PATH_LEN];
+	struct dirent *entry = NULL;
+	DIR *dir = opendir(root);
+
+	if(dir) {
+		entry = readdir(dir);
+	}
+
+	while (entry != NULL) {
+
+		if (strstr(entry->d_name, ".descriptor") != NULL) {
+
+			printf("DMU: Parsing entry '%s'\n", entry->d_name);
+
+			snprintf(path, MAX_PATH_LEN, "%s/%s", root, entry->d_name);
+			FILE *stream = fopen(path,"r");
+
+			if (stream != NULL){
+				dyn_message_type* msgType = NULL;
+
+				int rc = dynMessage_parse(stream, &msgType);
+				if (rc == 0 && msgType != NULL) {
+
+					char* msgName = NULL;
+					rc += dynMessage_getName(msgType,&msgName);
+
+					version_pt msgVersion = NULL;
+					rc += dynMessage_getVersion(msgType, &msgVersion);
+
+					if(rc == 0 && msgName != NULL && msgVersion != NULL){
+
+						unsigned int msgId = utils_stringHash(msgName);
+
+						pubsub_msg_serializer_t *msgSerializer = calloc(1,sizeof(pubsub_msg_serializer_t));
+
+						msgSerializer->handle = msgType;
+						msgSerializer->msgId = msgId;
+						msgSerializer->msgName = msgName;
+						msgSerializer->msgVersion = msgVersion;
+						msgSerializer->serialize = (void*) pubsubMsgSerializer_serialize;
+						msgSerializer->deserialize = (void*) pubsubMsgSerializer_deserialize;
+						msgSerializer->freeMsg = (void*) pubsubMsgSerializer_freeMsg;
+
+						bool clash = hashMap_containsKey(msgSerializers, (void*)(uintptr_t)msgId);
+						if (clash){
+							printf("Cannot add msg %s. clash in msg id %d!!\n", msgName, msgId);
+							free(msgSerializer);
+							dynMessage_destroy(msgType);
+						}
+						else if (msgId != 0){
+							printf("Adding %u : %s\n", msgId, msgName);
+							hashMap_put(msgSerializers, (void*)(uintptr_t)msgId, msgSerializer);
+						}
+						else{
+							printf("Error creating msg serializer\n");
+							free(msgSerializer);
+							dynMessage_destroy(msgType);
+						}
+
+					}
+					else{
+						printf("Cannot retrieve name and/or version from msg\n");
+					}
+
+				} else{
+					printf("DMU: cannot parse message from descriptor %s\n.",path);
+				}
+				fclose(stream);
+			}else{
+				printf("DMU: cannot open descriptor file %s\n.",path);
+			}
+
+		}
+		entry = readdir(dir);
+	}
+
+	if(dir) {
+		closedir(dir);
+	}
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.h b/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.h
new file mode 100644
index 0000000..c36f20e
--- /dev/null
+++ b/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.h
@@ -0,0 +1,55 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * pubsub_serializer_impl.h
+ *
+ *  \date       Mar 24, 2017
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_SERIALIZER_JSON_H_
+#define PUBSUB_SERIALIZER_JSON_H_
+
+#include "dyn_common.h"
+#include "dyn_type.h"
+#include "dyn_message.h"
+#include "log_helper.h"
+
+#include "pubsub_serializer.h"
+
+#define PUBSUB_SERIALIZER_TYPE	"json"
+
+typedef struct pubsub_serializer {
+	bundle_context_pt bundle_context;
+	log_helper_pt loghelper;
+} pubsub_serializer_t;
+
+celix_status_t pubsubSerializer_create(bundle_context_pt context, pubsub_serializer_t* *serializer);
+celix_status_t pubsubSerializer_destroy(pubsub_serializer_t* serializer);
+
+celix_status_t pubsubSerializer_createSerializerMap(pubsub_serializer_t* serializer, bundle_pt bundle, hash_map_pt* serializerMap);
+celix_status_t pubsubSerializer_destroySerializerMap(pubsub_serializer_t*, hash_map_pt serializerMap);
+
+/* Start of serializer specific functions */
+celix_status_t pubsubMsgSerializer_serialize(pubsub_msg_serializer_t* msgSerializer, const void* msg, void** out, size_t *outLen);
+celix_status_t pubsubMsgSerializer_deserialize(pubsub_msg_serializer_t* msgSerializer, const void* input, size_t inputLen, void **out);
+void pubsubMsgSerializer_freeMsg(pubsub_msg_serializer_t* msgSerializer, void *msg);
+
+#endif /* PUBSUB_SERIALIZER_JSON_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_topology_manager/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_topology_manager/CMakeLists.txt b/pubsub/pubsub_topology_manager/CMakeLists.txt
index b6eb796..784ca21 100644
--- a/pubsub/pubsub_topology_manager/CMakeLists.txt
+++ b/pubsub/pubsub_topology_manager/CMakeLists.txt
@@ -15,21 +15,12 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_admin/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("private/include")
-include_directories("public/include")
-
 add_bundle(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
     BUNDLE_SYMBOLICNAME "apache_celix_pubsub_topology_manager"
     VERSION "1.0.0"
     SOURCES
     	private/src/pstm_activator.c
     	private/src/pubsub_topology_manager.c
-	   ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
     	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
     	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c	
 )
@@ -38,7 +29,8 @@ bundle_files(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
    ${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include/pubsub_topic_info.descriptor
     DESTINATION "META-INF/descriptors/services"
 )
+target_link_libraries(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager PRIVATE Celix::framework Celix::log_helper)
+
 
-target_link_libraries(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager celix_framework celix_utils)
 install_bundle(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/test/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/test/CMakeLists.txt b/pubsub/test/CMakeLists.txt
index 8279c0c..65e22e5 100644
--- a/pubsub/test/CMakeLists.txt
+++ b/pubsub/test/CMakeLists.txt
@@ -31,7 +31,7 @@ add_bundle(pubsub_sut
         test/sut_activator.c
     VERSION 1.0.0
 )
-target_link_libraries(pubsub_sut celix_framework celix_utils)
+target_link_libraries(pubsub_sut PRIVATE Celix::framework)
 bundle_files(pubsub_sut
     msg_descriptors/msg.descriptor
     msg_descriptors/sync.descriptor
@@ -66,9 +66,9 @@ add_bundle(pubsub_tst
 )
 if (APPLE)
     #Note that the launcher celix_test_runner is linked with CppuTest, not the bundle libs. Default libCppUTest.a is not compiled for relocation 
-    target_link_libraries(pubsub_tst celix_framework celix_utils -Wl,-undefined -Wl,dynamic_lookup)
+    target_link_libraries(pubsub_tst PRIVATE Celix::framework -Wl,-undefined -Wl,dynamic_lookup)
 else ()
-    target_link_libraries(pubsub_tst celix_framework celix_utils)
+    target_link_libraries(pubsub_tst PRIVATE Celix::framework)
 endif ()
 
 bundle_files(pubsub_tst

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/CMakeLists.txt b/remote_services/CMakeLists.txt
index 767ece7..7ca1c44 100644
--- a/remote_services/CMakeLists.txt
+++ b/remote_services/CMakeLists.txt
@@ -21,14 +21,16 @@ if (REMOTE_SERVICE_ADMIN)
     add_subdirectory(examples)
 
     add_subdirectory(topology_manager)
- 
+
+    add_subdirectory(discovery_common)
     add_subdirectory(discovery_configured)
     add_subdirectory(discovery_etcd)
     add_subdirectory(discovery_shm)
 
     #TODO refactor shm rsa to use dfi
+    add_subdirectory(remote_service_admin_api)
+    add_subdirectory(remote_service_admin_common)
     #add_subdirectory(remote_service_admin_shm)
-    add_subdirectory(remote_service_admin)
     add_subdirectory(remote_service_admin_dfi)
 
 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/discovery.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/discovery.h b/remote_services/discovery/private/include/discovery.h
deleted file mode 100644
index ee79caf..0000000
--- a/remote_services/discovery/private/include/discovery.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * discovery.h
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef DISCOVERY_H_
-#define DISCOVERY_H_
-
-#include "bundle_context.h"
-#include "service_reference.h"
-
-#include "endpoint_description.h"
-#include "endpoint_listener.h"
-
-#define DISCOVERY_SERVER_INTERFACE	"DISCOVERY_CFG_SERVER_INTERFACE"
-#define DISCOVERY_SERVER_IP 		"DISCOVERY_CFG_SERVER_IP"
-#define DISCOVERY_SERVER_PORT 		"DISCOVERY_CFG_SERVER_PORT"
-#define DISCOVERY_SERVER_PATH 		"DISCOVERY_CFG_SERVER_PATH"
-#define DISCOVERY_POLL_ENDPOINTS 	"DISCOVERY_CFG_POLL_ENDPOINTS"
-#define DISCOVERY_SERVER_MAX_EP	"DISCOVERY_CFG_SERVER_MAX_EP"
-
-typedef struct discovery *discovery_pt;
-
-
-/* those one could be put into a general discovery.h - file */
-celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery);
-celix_status_t discovery_destroy(discovery_pt discovery);
-
-celix_status_t discovery_start(discovery_pt discovery);
-celix_status_t discovery_stop(discovery_pt discovery);
-
-celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
-celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
-
-celix_status_t discovery_endpointListenerAdding(void * handle, service_reference_pt reference, void **service);
-celix_status_t discovery_endpointListenerAdded(void * handle, service_reference_pt reference, void * service);
-celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service);
-celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service);
-
-celix_status_t discovery_informEndpointListeners(discovery_pt discovery, endpoint_description_pt endpoint, bool endpointAdded);
-celix_status_t discovery_updateEndpointListener(discovery_pt discovery, service_reference_pt reference, endpoint_listener_pt service);
-
-celix_status_t discovery_addDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint);
-celix_status_t discovery_removeDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint);
-
-#endif /* DISCOVERY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_descriptor_common.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_descriptor_common.h b/remote_services/discovery/private/include/endpoint_descriptor_common.h
deleted file mode 100644
index a186a18..0000000
--- a/remote_services/discovery/private/include/endpoint_descriptor_common.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_descriptor_common.h
- *
- * \date		Aug 8, 2014
- * \author		<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright	Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DESCRIPTOR_COMMON_H_
-#define ENDPOINT_DESCRIPTOR_COMMON_H_
-
-/*
- * Private constant & enum definitions for endpoint descriptor reader and writer, not needed for normal usage of the reader and writer.
- */
-
-typedef enum {
-    VALUE_TYPE_STRING,
-    VALUE_TYPE_LONG,
-    VALUE_TYPE_DOUBLE,
-    VALUE_TYPE_FLOAT,
-    VALUE_TYPE_INTEGER,
-    VALUE_TYPE_BYTE,
-    VALUE_TYPE_CHAR,
-    VALUE_TYPE_BOOLEAN,
-    VALUE_TYPE_SHORT,
-} valueType;
-
-static const __attribute__((unused)) xmlChar* XML = (const xmlChar*) "xml";
-static const __attribute__((unused)) xmlChar* XMLNS = (const xmlChar*) "http://www.osgi.org/xmlns/rsa/v1.0.0";
-
-static const __attribute__((unused)) xmlChar* ENDPOINT_DESCRIPTIONS = (const xmlChar*) "endpoint-descriptions";
-static const xmlChar* ENDPOINT_DESCRIPTION = (const xmlChar*) "endpoint-description";
-
-static const xmlChar* ARRAY = (const xmlChar*) "array";
-static const __attribute__((unused)) xmlChar* LIST = (const xmlChar*) "list";
-static const __attribute__((unused)) xmlChar* SET = (const xmlChar*) "set";
-
-static const xmlChar* PROPERTY = (const xmlChar*) "property";
-static const xmlChar* NAME = (const xmlChar*) "name";
-static const xmlChar* VALUE = (const xmlChar*) "value";
-static const xmlChar* VALUE_TYPE = (const xmlChar*) "value-type";
-
-#endif /* ENDPOINT_DESCRIPTOR_COMMON_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_descriptor_reader.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_descriptor_reader.h b/remote_services/discovery/private/include/endpoint_descriptor_reader.h
deleted file mode 100644
index 7a05d9e..0000000
--- a/remote_services/discovery/private/include/endpoint_descriptor_reader.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_descriptor_reader.h
- *
- *  \date       26 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DESCRIPTOR_READER_H_
-#define ENDPOINT_DESCRIPTOR_READER_H_
-
-#include "endpoint_discovery_poller.h"
-#include "celix_errno.h"
-#include "array_list.h"
-
-typedef struct endpoint_descriptor_reader *endpoint_descriptor_reader_pt;
-
-celix_status_t endpointDescriptorReader_create(endpoint_discovery_poller_pt poller, endpoint_descriptor_reader_pt *reader);
-celix_status_t endpointDescriptorReader_destroy(endpoint_descriptor_reader_pt reader);
-
-celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_pt reader, char *document, array_list_pt *endpoints);
-
-
-#endif /* ENDPOINT_DESCRIPTOR_READER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_descriptor_writer.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_descriptor_writer.h b/remote_services/discovery/private/include/endpoint_descriptor_writer.h
deleted file mode 100644
index 3c5a9be..0000000
--- a/remote_services/discovery/private/include/endpoint_descriptor_writer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_descriptor_writer.h
- *
- *  \date       26 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DESCRIPTOR_WRITER_H_
-#define ENDPOINT_DESCRIPTOR_WRITER_H_
-
-#include "celix_errno.h"
-#include "array_list.h"
-
-typedef struct endpoint_descriptor_writer *endpoint_descriptor_writer_pt;
-
-celix_status_t endpointDescriptorWriter_create(endpoint_descriptor_writer_pt *writer);
-celix_status_t endpointDescriptorWriter_destroy(endpoint_descriptor_writer_pt writer);
-celix_status_t endpointDescriptorWriter_writeDocument(endpoint_descriptor_writer_pt writer, array_list_pt endpoints, char **document);
-
-#endif /* ENDPOINT_DESCRIPTOR_WRITER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_discovery_poller.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_discovery_poller.h b/remote_services/discovery/private/include/endpoint_discovery_poller.h
deleted file mode 100644
index d344e55..0000000
--- a/remote_services/discovery/private/include/endpoint_discovery_poller.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_discovery_poller.h
- *
- * \date       3 Jul 2014
- * \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright  Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DISCOVERY_POLLER_H_
-#define ENDPOINT_DISCOVERY_POLLER_H_
-
-#include "celix_errno.h"
-#include "discovery.h"
-#include "log_helper.h"
-
-struct endpoint_discovery_poller {
-    discovery_pt discovery;
-    hash_map_pt entries;
-    log_helper_pt* loghelper;
-
-    celix_thread_mutex_t pollerLock;
-    celix_thread_t pollerThread;
-
-    unsigned int poll_interval;
-    volatile bool running;
-};
-
-typedef struct endpoint_discovery_poller *endpoint_discovery_poller_pt;
-
-celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller);
-celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller);
-
-celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url);
-celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url);
-
-celix_status_t endpointDiscoveryPoller_getDiscoveryEndpoints(endpoint_discovery_poller_pt poller, array_list_pt urls);
-
-#endif /* ENDPOINT_DISCOVERY_POLLER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_discovery_server.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_discovery_server.h b/remote_services/discovery/private/include/endpoint_discovery_server.h
deleted file mode 100644
index 51082b5..0000000
--- a/remote_services/discovery/private/include/endpoint_discovery_server.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_discovery_server.h
- *
- * \date		Aug 12, 2014
- * \author		<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright	Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DISCOVERY_SERVER_H_
-#define ENDPOINT_DISCOVERY_SERVER_H_
-
-#include "celix_errno.h"
-#include "discovery.h"
-
-typedef struct endpoint_discovery_server *endpoint_discovery_server_pt;
-
-/**
- * Creates and starts a new instance of an endpoint discovery server.
- *
- * @param discovery [in] the discovery service itself;
- * @param context [in] the bundle context;
- * @param server [out] the pointer to the created instance.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server);
-
-/**
- * Stops and destroys a given instance of an endpoint discovery server.
- *
- * @param server [in] the pointer to the instance to destroy.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt server);
-
-/**
- * Adds a given endpoint description to expose through the given discovery server.
- *
- * @param server [in] the endpoint discovery server to expose the endpoint through;
- * @param endpoint [in] the endpoint description to expose.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint);
-
-/**
- * Removes a given endpoint description from exposure through the given discovery server.
- *
- * @param server [in] the endpoint discovery server to remove the endpoint from;
- * @param endpoint [in] the endpoint description to remove.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_removeEndpoint( endpoint_discovery_server_pt server, endpoint_description_pt endpoint);
-
-/**
- * Returns the url, which is used by the discovery server to announce the endpoints
- *
- * @param server [in] the endpoint discovery server to retrieve the url from
- * @param url [out] url which is used to announce the endpoints.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_getUrl(endpoint_discovery_server_pt server, char* url);
-
-
-#endif /* ENDPOINT_DISCOVERY_SERVER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/desc.xml
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/desc.xml b/remote_services/discovery/private/src/desc.xml
deleted file mode 100644
index 5998992..0000000
--- a/remote_services/discovery/private/src/desc.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- -->
-<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
-	<endpoint-description>
-		<property name="service.intents">
-			<list>
-				<value>SOAP</value>
-				<value>HTTP</value>
-			</list>
-		</property>
-		<property name="endpoint.id" value="http://ws.acme.com:9000/hello" />
-		<property name="objectClass" value="com.acme.Foo" />
-		<property name="endpoint.package.version.com.acme" value="4.2" />
-		<property name="service.imported.configs" value="com.acme" />
-		<property name="com.acme.ws.xml">
-			<xml>
-				<config xmlns="http://acme.com/defs">
-					<port>1029</port>
-					<host>www.acme.com</host>
-				</config>
-			</xml>
-		</property>
-	</endpoint-description>
-</endpoint-descriptions>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/discovery.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/discovery.c b/remote_services/discovery/private/src/discovery.c
deleted file mode 100644
index e40a887..0000000
--- a/remote_services/discovery/private/src/discovery.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery.c
- *
- * \date        Aug 8, 2014
- * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright	Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdbool.h>
-#include <netdb.h>
-#include <string.h>
-
-#include "celix_threads.h"
-#include "bundle_context.h"
-#include "log_helper.h"
-#include "discovery.h"
-#include "discovery_impl.h"
-
-
-celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
-	celix_status_t status;
-	discovery_pt discovery = handle;
-
-	logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Endpoint for %s, with filter \"%s\" added...", endpoint->service, matchedFilter);
-
-	status = endpointDiscoveryServer_addEndpoint(discovery->server, endpoint);
-
-	return status;
-}
-
-celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
-	celix_status_t status;
-	discovery_pt discovery = handle;
-
-	logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Endpoint for %s, with filter \"%s\" removed...", endpoint->service, matchedFilter);
-
-	status = endpointDiscoveryServer_removeEndpoint(discovery->server, endpoint);
-
-	return status;
-}
-
-celix_status_t discovery_endpointListenerAdding(void* handle, service_reference_pt reference, void** service) {
-	celix_status_t status = CELIX_SUCCESS;
-	discovery_pt discovery = handle;
-
-	bundleContext_getService(discovery->context, reference, service);
-
-	return status;
-}
-
-celix_status_t discovery_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) {
-	celix_status_t status = CELIX_SUCCESS;
-	discovery_pt discovery = handle;
-
-	const char *discoveryListener = NULL;
-	serviceReference_getProperty(reference, "DISCOVERY", &discoveryListener);
-	const char *scope = NULL;
-	serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
-	filter_pt filter = filter_create(scope);
-
-	if (discoveryListener != NULL && strcmp(discoveryListener, "true") == 0) {
-		logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Ignored - Discovery listener");
-	} else {
-		celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
-		hash_map_iterator_pt iter = hashMapIterator_create(discovery->discoveredServices);
-		while (hashMapIterator_hasNext(iter)) {
-			endpoint_description_pt endpoint = hashMapIterator_nextValue(iter);
-
-			bool matchResult = false;
-			filter_match(filter, endpoint->properties, &matchResult);
-			if (matchResult) {
-				endpoint_listener_pt listener = service;
-
-				logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Added - Add Scope");
-
-				listener->endpointAdded(listener->handle, endpoint, NULL);
-			}
-		}
-		hashMapIterator_destroy(iter);
-
-		celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
-		celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
-		hashMap_put(discovery->listenerReferences, reference, NULL);
-
-		celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
-	}
-
-	filter_destroy(filter);
-
-	return status;
-}
-
-celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status;
-
-	status = discovery_endpointListenerRemoved(handle, reference, service);
-	if (status == CELIX_SUCCESS) {
-        status = discovery_endpointListenerAdded(handle, reference, service);
-	}
-
-	return status;
-}
-
-celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) {
-    celix_status_t status;
-    discovery_pt discovery = handle;
-
-    status = celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
-    if (status == CELIX_SUCCESS) {
-        if (discovery->listenerReferences != NULL) {
-            if (hashMap_remove(discovery->listenerReferences, reference)) {
-                logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
-            }
-        }
-
-        status = celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
-    }
-
-	return status;
-}
-
-celix_status_t discovery_informEndpointListeners(discovery_pt discovery, endpoint_description_pt endpoint, bool endpointAdded) {
-	celix_status_t status;
-
-	// Inform listeners of new endpoint
-	status = celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
-    if (status == CELIX_SUCCESS) {
-        if (discovery->listenerReferences != NULL) {
-            hash_map_iterator_pt iter = hashMapIterator_create(discovery->listenerReferences);
-            while (hashMapIterator_hasNext(iter)) {
-                hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
-                service_reference_pt reference = hashMapEntry_getKey(entry);
-                endpoint_listener_pt listener = NULL;
-
-                const char* scope = NULL;
-                serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
-                filter_pt filter = filter_create(scope);
-                bool matchResult = false;
-
-                status = filter_match(filter, endpoint->properties, &matchResult);
-                if (status == CELIX_SUCCESS) {
-                    if (matchResult) {
-                        bundleContext_getService(discovery->context, reference, (void **) &listener);
-                        if (endpointAdded) {
-                            logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Adding service (%s)", endpoint->service);
-
-                            listener->endpointAdded(listener->handle, endpoint, (char*)scope);
-                        } else {
-                            logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Removing service (%s)", endpoint->service);
-
-                            listener->endpointRemoved(listener->handle, endpoint, (char*)scope);
-                        }
-                    }
-
-                    filter_destroy(filter);
-                }
-            }
-            hashMapIterator_destroy(iter);
-        }
-
-        status = celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
-    }
-
-	return status;
-}
-
-celix_status_t discovery_addDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
-    if (status == CELIX_SUCCESS) {
-        char *endpointId = endpoint->id;
-        bool exists = hashMap_get(discovery->discoveredServices, endpointId) != NULL;
-        if (!exists) {
-            hashMap_put(discovery->discoveredServices, endpointId, endpoint);
-        }
-
-        status = celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
-        if (!exists) {
-            // notify our listeners that a new endpoint is available...
-            discovery_informEndpointListeners(discovery, endpoint, true /* addingService */);
-        }
-    }
-
-	return status;
-}
-
-celix_status_t discovery_removeDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
-    if (status == CELIX_SUCCESS) {
-        char *endpointId = endpoint->id;
-        void *oldValue = hashMap_remove(discovery->discoveredServices, endpointId);
-
-        status = celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
-        if (oldValue) {
-            status = discovery_informEndpointListeners(discovery, endpoint, false /* removeService */);
-        }
-    }
-
-	return status;
-}


[14/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/discovery_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/discovery_activator.c b/remote_services/discovery/private/src/discovery_activator.c
deleted file mode 100644
index 3267d25..0000000
--- a/remote_services/discovery/private/src/discovery_activator.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery_activator.c
- *
- * \date        Aug 8, 2014
- * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright	Apache License, Version 2.0
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#include "bundle_activator.h"
-#include "service_tracker.h"
-#include "constants.h"
-
-#include "log_helper.h"
-#include "discovery.h"
-#include "remote_constants.h"
-
-struct activator {
-	bundle_context_pt context;
-	discovery_pt discovery;
-	log_helper_pt loghelper;
-
-	service_tracker_pt endpointListenerTracker;
-	endpoint_listener_pt endpointListener;
-	service_registration_pt endpointListenerService;
-};
-
-celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) {
-	celix_status_t status;
-
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(activator->discovery, discovery_endpointListenerAdding, discovery_endpointListenerAdded, discovery_endpointListenerModified,
-			discovery_endpointListenerRemoved, &customizer);
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker);
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status;
-
-	struct activator* activator = calloc(1,sizeof(struct activator));
-	if (!activator) {
-		return CELIX_ENOMEM;
-	}
-
-	status = discovery_create(context, &activator->discovery);
-	if (status == CELIX_SUCCESS) {
-		activator->context = context;
-
-		logHelper_create(context, &activator->loghelper);
-
-		status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
-		if(status==CELIX_SUCCESS){
-			*userData = activator;
-		}
-		else{
-			bundleActivator_destroy(activator,context);
-		}
-	}
-	else{
-		free(activator);
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	celix_status_t status;
-	struct activator *activator = userData;
-	const char *uuid = NULL;
-
-	logHelper_start(activator->loghelper);
-
-	status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-	if (!uuid) {
-		logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "no framework UUID defined?!");
-		return CELIX_ILLEGAL_STATE;
-	}
-
-	size_t len = 11 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
-	char *scope = malloc(len + 1);
-	if (!scope) {
-		return CELIX_ENOMEM;
-	}
-
-	sprintf(scope, "(&(%s=*)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
-	scope[len] = 0;
-
-	logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "using scope %s.", scope);
-
-	properties_pt props = properties_create();
-	properties_set(props, "DISCOVERY", "true");
-	properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_open(activator->endpointListenerTracker);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = discovery_start(activator->discovery);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		endpoint_listener_pt endpointListener = calloc(1, sizeof(struct endpoint_listener));
-
-		if (endpointListener) {
-			endpointListener->handle = activator->discovery;
-			endpointListener->endpointAdded = discovery_endpointAdded;
-			endpointListener->endpointRemoved = discovery_endpointRemoved;
-
-			status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService);
-
-			if (status == CELIX_SUCCESS) {
-				activator->endpointListener = endpointListener;
-			}
-		}
-	}
-	// We can release the scope, as properties_set makes a copy of the key & value...
-	free(scope);
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-	celix_status_t status;
-	struct activator *activator = userData;
-
-	status = discovery_stop(activator->discovery);
-
-	status = serviceTracker_close(activator->endpointListenerTracker);
-
-	status = serviceRegistration_unregister(activator->endpointListenerService);
-	free(activator->endpointListener);
-
-	logHelper_stop(activator->loghelper);
-
-	return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status;
-	struct activator *activator = userData;
-
-	status = serviceTracker_destroy(activator->endpointListenerTracker);
-
-	status = discovery_destroy(activator->discovery);
-
-	logHelper_destroy(&activator->loghelper);
-
-	activator->loghelper = NULL;
-	activator->endpointListenerTracker = NULL;
-	activator->endpointListenerService = NULL;
-	activator->discovery = NULL;
-	activator->context = NULL;
-
-	free(activator);
-
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_descriptor_reader.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/endpoint_descriptor_reader.c b/remote_services/discovery/private/src/endpoint_descriptor_reader.c
deleted file mode 100644
index ea176bf..0000000
--- a/remote_services/discovery/private/src/endpoint_descriptor_reader.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_descriptor_reader.c
- *
- *  \date       24 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#include <stdbool.h>
-#include <string.h>
-#include <libxml/xmlreader.h>
-
-#include "log_helper.h"
-#include "remote_constants.h"
-
-#include "endpoint_description.h"
-#include "endpoint_descriptor_common.h"
-#include "endpoint_descriptor_reader.h"
-
-struct endpoint_descriptor_reader {
-    xmlTextReaderPtr reader;
-    log_helper_pt* loghelper;
-};
-
-static valueType valueTypeFromString(char *name);
-
-celix_status_t endpointDescriptorReader_create(endpoint_discovery_poller_pt poller, endpoint_descriptor_reader_pt *reader) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    *reader = malloc(sizeof(**reader));
-    if (!*reader) {
-        status = CELIX_ENOMEM;
-    } else {
-        (*reader)->reader = NULL;
-        (*reader)->loghelper = poller->loghelper;
-    }
-
-    return status;
-}
-
-celix_status_t endpointDescriptorReader_destroy(endpoint_descriptor_reader_pt reader) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    reader->loghelper = NULL;
-
-    free(reader);
-
-    return status;
-}
-
-void endpointDescriptorReader_addSingleValuedProperty(properties_pt properties, const xmlChar* name, const xmlChar* value) {
-	properties_set(properties, (char *) name, (char*) value);
-}
-
-void endpointDescriptorReader_addMultiValuedProperty(properties_pt properties, const xmlChar* name, array_list_pt values) {
-	char *value = calloc(256, sizeof(*value));
-	if (value) {
-		unsigned int size = arrayList_size(values);
-        unsigned int i;
-        for (i = 0; i < size; i++) {
-			char* item = (char*) arrayList_get(values, i);
-			if (i > 0) {
-				value = strcat(value, ",");
-			}
-			value = strcat(value, item);
-		}
-
-		properties_set(properties, (char *) name, value);
-
-		free(value);
-	}
-}
-
-celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_pt reader, char *document, array_list_pt *endpoints) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    reader->reader = xmlReaderForMemory(document, (int) strlen(document), NULL, "UTF-8", 0);
-    if (reader->reader == NULL) {
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        bool inProperty = false;
-        bool inXml = false;
-        bool inArray = false;
-        bool inList = false;
-        bool inSet = false;
-        bool inValue = false;
-
-        const xmlChar *propertyName = NULL;
-        const xmlChar *propertyValue = NULL;
-        valueType propertyType = VALUE_TYPE_STRING;
-        xmlChar *valueBuffer = xmlMalloc(256);
-        valueBuffer[0] = '\0';
-
-        array_list_pt propertyValues = NULL;
-        arrayList_create(&propertyValues);
-
-        array_list_pt endpointDescriptions = NULL;
-        if (*endpoints) {
-        	// use the given arraylist...
-        	endpointDescriptions = *endpoints;
-        } else {
-			arrayList_create(&endpointDescriptions);
-			// return the read endpoints...
-			*endpoints = endpointDescriptions;
-        }
-
-        properties_pt endpointProperties = NULL;
-
-        int read = xmlTextReaderRead(reader->reader);
-        while (read == XML_TEXTREADER_MODE_INTERACTIVE) {
-            int type = xmlTextReaderNodeType(reader->reader);
-
-            if (type == XML_READER_TYPE_ELEMENT) {
-                const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
-
-                if (inXml) {
-                    valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "<");
-                    valueBuffer = xmlStrcat(valueBuffer, localname);
-
-                    int i = xmlTextReaderMoveToFirstAttribute(reader->reader);
-                    while (i == 1) {
-                        const xmlChar *name = xmlTextReaderConstName(reader->reader);
-                        const xmlChar *value = xmlTextReaderConstValue(reader->reader);
-
-                        valueBuffer = xmlStrcat(valueBuffer, BAD_CAST " ");
-                        valueBuffer = xmlStrcat(valueBuffer, name);
-                        valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "=\"");
-                        valueBuffer = xmlStrcat(valueBuffer, BAD_CAST value);
-                        valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "\"");
-
-                        i = xmlTextReaderMoveToNextAttribute(reader->reader);
-                    }
-
-                    valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
-                } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
-
-                	if (endpointProperties != NULL)
-                		properties_destroy(endpointProperties);
-
-                    endpointProperties = properties_create();
-                } else if (xmlStrcmp(localname, PROPERTY) == 0) {
-                    inProperty = true;
-
-                    propertyName = xmlTextReaderGetAttribute(reader->reader, NAME);
-                    propertyValue = xmlTextReaderGetAttribute(reader->reader, VALUE);
-                    xmlChar *vtype = xmlTextReaderGetAttribute(reader->reader, VALUE_TYPE);
-                    propertyType = valueTypeFromString((char*) vtype);
-                    arrayList_clear(propertyValues);
-
-                    if (xmlTextReaderIsEmptyElement(reader->reader)) {
-                        inProperty = false;
-
-                        if (propertyValue != NULL) {
-                        	endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
-                        }
-
-                        xmlFree((void *) propertyName);
-                        xmlFree((void *) propertyValue);
-                        xmlFree((void *) vtype);
-                    }
-                } else {
-                    valueBuffer[0] = 0;
-                    inArray |= inProperty && xmlStrcmp(localname, ARRAY) == 0;
-                    inList |= inProperty && xmlStrcmp(localname, LIST) == 0;
-                    inSet |= inProperty && xmlStrcmp(localname, SET) == 0;
-                    inXml |= inProperty && xmlStrcmp(localname, XML) == 0;
-                    inValue |= inProperty && xmlStrcmp(localname, VALUE) == 0;
-				}
-			} else if (type == XML_READER_TYPE_END_ELEMENT) {
-				const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
-
-                if (inXml) {
-                    if (xmlStrcmp(localname, XML) != 0)  {
-                    	valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "</");
-                    	valueBuffer = xmlStrcat(valueBuffer, localname);
-                    	valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
-                    }
-                    else {
-                        inXml = false;
-                    }
-                } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
-                    endpoint_description_pt endpointDescription = NULL;
-                    // Completely parsed endpoint description, add it to our list of results...
-                    if(endpointDescription_create(endpointProperties, &endpointDescription) == CELIX_SUCCESS){
-			arrayList_add(endpointDescriptions, endpointDescription);
-                    }
-
-                    endpointProperties = properties_create();
-                } else if (xmlStrcmp(localname, PROPERTY) == 0) {
-                    inProperty = false;
-
-                    if (inArray || inList || inSet) {
-						endpointDescriptorReader_addMultiValuedProperty(endpointProperties, propertyName, propertyValues);
-                    }
-                    else if (propertyValue != NULL) {
-                    	if (propertyType != VALUE_TYPE_STRING) {
-                    		logHelper_log(*reader->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_DESCRIPTOR_READER: Only string support for %s\n", propertyName);
-                    	}
-                    	endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
-
-                        xmlFree((void *) propertyValue);
-                    }
-                    else {
-                    	endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, valueBuffer);
-                    }
-
-                    xmlFree((void *) propertyName);
-					unsigned int k=0;
-					for(;k<arrayList_size(propertyValues);k++){
-						free(arrayList_get(propertyValues,k));
-					}
-                    arrayList_clear(propertyValues);
-
-                    propertyType = VALUE_TYPE_STRING;
-                    inArray = false;
-                    inList = false;
-                    inSet = false;
-                    inXml = false;
-                } else if (xmlStrcmp(localname, VALUE) == 0) {
-                    arrayList_add(propertyValues, strdup((char*) valueBuffer));
-                    valueBuffer[0] = 0;
-                    inValue = false;
-                }
-            } else if (type == XML_READER_TYPE_TEXT) {
-                if (inValue || inXml) {
-                    const xmlChar *value = xmlTextReaderValue(reader->reader);
-                    valueBuffer = xmlStrcat(valueBuffer, value);
-                    xmlFree((void *)value);
-                }
-            }
-
-            read = xmlTextReaderRead(reader->reader);
-        }
-
-		if(endpointProperties!=NULL){
-			properties_destroy(endpointProperties);
-		}
-
-		unsigned int k=0;
-		for(;k<arrayList_size(propertyValues);k++){
-			free(arrayList_get(propertyValues,k));
-		}
-        arrayList_destroy(propertyValues);
-        xmlFree(valueBuffer);
-
-        xmlFreeTextReader(reader->reader);
-    }
-
-    return status;
-}
-
-static valueType valueTypeFromString(char *name) {
-    if (name == NULL || strcmp(name, "") == 0 || strcmp(name, "String") == 0) {
-        return VALUE_TYPE_STRING;
-    } else if (strcmp(name, "long") == 0 || strcmp(name, "Long") == 0) {
-        return VALUE_TYPE_LONG;
-    } else if (strcmp(name, "double") == 0 || strcmp(name, "Double") == 0) {
-        return VALUE_TYPE_DOUBLE;
-    } else if (strcmp(name, "float") == 0 || strcmp(name, "Float") == 0) {
-        return VALUE_TYPE_FLOAT;
-    } else if (strcmp(name, "int") == 0 || strcmp(name, "integer") == 0 || strcmp(name, "Integer") == 0) {
-        return VALUE_TYPE_INTEGER;
-    } else if (strcmp(name, "short") == 0 || strcmp(name, "Short") == 0) {
-        return VALUE_TYPE_SHORT;
-    } else if (strcmp(name, "byte") == 0 || strcmp(name, "Byte") == 0) {
-        return VALUE_TYPE_BYTE;
-    } else if (strcmp(name, "char") == 0 || strcmp(name, "Character") == 0) {
-        return VALUE_TYPE_CHAR;
-    } else if (strcmp(name, "boolean") == 0 || strcmp(name, "Boolean") == 0) {
-        return VALUE_TYPE_BOOLEAN;
-    } else {
-        return VALUE_TYPE_STRING;
-    }
-}
-
-#ifdef RSA_ENDPOINT_TEST_READER
-int main() {
-    array_list_pt list = NULL;
-    endpoint_descriptor_reader_pt reader = NULL;
-
-    char *doc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-"<endpoint-descriptions xmlns=\"http://www.osgi.org/xmlns/rsa/v1.0.0\">"
-    "<endpoint-description>"
-    	"<property name=\"endpoint.service.id\" value-type=\"long\" value=\"6\"/>"
-		"<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
-        "<property name=\"service.intents\">"
-            "<list>"
-                "<value>SOAP</value>"
-                "<value>HTTP</value>"
-            "</list>"
-        "</property>"
-        "<property name=\"endpoint.id\" value=\"11111111-1111-1111-1111-111111111111\" />"
-        "<property name=\"objectClass\"><array><value>com.acme.Foo</value></array></property>"
-        "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
-        "<property name=\"service.imported.configs\" value=\"com.acme\" />"
-    	"<property name=\"service.imported\" value=\"true\"/>"
-        "<property name=\"com.acme.ws.xml\">"
-            "<xml>"
-                "<config xmlns=\"http://acme.com/defs\">"
-                    "<port>1029</port>"
-                    "<host>www.acme.com</host>"
-                "</config>"
-            "</xml>"
-        "</property>"
-    "</endpoint-description>"
-		"<endpoint-description>"
-        	"<property name=\"endpoint.service.id\" value-type=\"long\" value=\"5\"/>"
-    		"<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
-			"<property name=\"service.intents\">"
-				"<list>"
-					"<value>SOAP</value>"
-					"<value>HTTP</value>"
-				"</list>"
-			"</property>"
-			"<property name=\"endpoint.id\" value=\"22222222-2222-2222-2222-222222222222\" />"
-            "<property name=\"objectClass\"><array><value>com.acme.Bar</value></array></property>"
-			"<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
-			"<property name=\"service.imported.configs\" value=\"com.acme\" />"
-			"<property name=\"com.acme.ws.xml\">"
-				"<xml>"
-					"<config xmlns=\"http://acme.com/defs\">"
-						"<port>1029</port>"
-						"<host>www.acme.com</host>"
-					"</config>"
-				"</xml>"
-			"</property>"
-		"</endpoint-description>"
-	"</endpoint-descriptions>";
-
-	endpointDescriptorReader_create(&reader);
-
-	endpointDescriptorReader_parseDocument(reader, doc, &list);
-
-	int i;
-	for (i = 0; i < arrayList_size(list); i++) {
-		printf("\nEndpoint description #%d:\n", (i+1));
-		endpoint_description_pt edp = arrayList_get(list, i);
-		printf("Id: %s\n", edp->id);
-		printf("Service Id: %lu\n", edp->serviceId);
-		printf("Framework UUID: %s\n", edp->frameworkUUID);
-		printf("Service: %s\n", edp->service);
-
-		properties_pt props = edp->properties;
-		if (props) {
-			printf("Service properties:\n");
-			hash_map_iterator_pt iter = hashMapIterator_create(props);
-			while (hashMapIterator_hasNext(iter)) {
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
-				printf("- %s => '%s'\n", hashMapEntry_getKey(entry), hashMapEntry_getValue(entry));
-			}
-			hashMapIterator_destroy(iter);
-		} else {
-			printf("No service properties...\n");
-		}
-
-
-		endpointDescription_destroy(edp);
-	}
-
-	if (list != NULL) {
-		arrayList_destroy(list);
-	}
-
-	endpointDescriptorReader_destroy(reader);
-
-    return 0;
-}
-#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_descriptor_writer.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/endpoint_descriptor_writer.c b/remote_services/discovery/private/src/endpoint_descriptor_writer.c
deleted file mode 100644
index 71b07b4..0000000
--- a/remote_services/discovery/private/src/endpoint_descriptor_writer.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_descriptor_writer.c
- *
- *  \date       26 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <string.h>
-#include <libxml/xmlwriter.h>
-
-#include "constants.h"
-#include "remote_constants.h"
-
-#include "endpoint_description.h"
-#include "endpoint_descriptor_common.h"
-#include "endpoint_descriptor_writer.h"
-
-struct endpoint_descriptor_writer {
-    xmlBufferPtr buffer;
-    xmlTextWriterPtr writer;
-};
-
-static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint);
-
-static char* valueTypeToString(valueType type);
-
-celix_status_t endpointDescriptorWriter_create(endpoint_descriptor_writer_pt *writer) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    *writer = malloc(sizeof(**writer));
-    if (!*writer) {
-        status = CELIX_ENOMEM;
-    } else {
-        (*writer)->buffer = xmlBufferCreate();
-        if ((*writer)->buffer == NULL) {
-            status = CELIX_BUNDLE_EXCEPTION;
-        } else {
-            (*writer)->writer = xmlNewTextWriterMemory((*writer)->buffer, 0);
-            if ((*writer)->writer == NULL) {
-                status = CELIX_BUNDLE_EXCEPTION;
-            }
-        }
-    }
-
-    return status;
-}
-
-celix_status_t endpointDescriptorWriter_destroy(endpoint_descriptor_writer_pt writer) {
-    xmlFreeTextWriter(writer->writer);
-    xmlBufferFree(writer->buffer);
-    free(writer);
-    return CELIX_SUCCESS;
-}
-
-celix_status_t endpointDescriptorWriter_writeDocument(endpoint_descriptor_writer_pt writer, array_list_pt endpoints, char **document) {
-    celix_status_t status = CELIX_SUCCESS;
-    int rc;
-
-    rc = xmlTextWriterStartDocument(writer->writer, NULL, "UTF-8", NULL);
-    if (rc < 0) {
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        rc = xmlTextWriterStartElementNS(writer->writer, NULL, ENDPOINT_DESCRIPTIONS, XMLNS);
-        if (rc < 0) {
-            status = CELIX_BUNDLE_EXCEPTION;
-        } else {
-            unsigned int i;
-            for (i = 0; i < arrayList_size(endpoints); i++) {
-                endpoint_description_pt endpoint = arrayList_get(endpoints, i);
-                status = endpointDescriptorWriter_writeEndpoint(writer, endpoint);
-            }
-            if (status == CELIX_SUCCESS) {
-                rc = xmlTextWriterEndElement(writer->writer);
-                if (rc < 0) {
-                    status = CELIX_BUNDLE_EXCEPTION;
-                } else {
-                    rc = xmlTextWriterEndDocument(writer->writer);
-                    if (rc < 0) {
-                        status = CELIX_BUNDLE_EXCEPTION;
-                    } else {
-                        *document = (char *) writer->buffer->content;
-                    }
-                }
-            }
-        }
-    }
-
-    return status;
-}
-
-static celix_status_t endpointDescriptorWriter_writeArrayValue(xmlTextWriterPtr writer, const xmlChar* value) {
-    xmlTextWriterStartElement(writer, ARRAY);
-    xmlTextWriterStartElement(writer, VALUE);
-    xmlTextWriterWriteString(writer, value);
-    xmlTextWriterEndElement(writer); // value
-    xmlTextWriterEndElement(writer); // array
-
-	return CELIX_SUCCESS;
-}
-
-static celix_status_t endpointDescriptorWriter_writeTypedValue(xmlTextWriterPtr writer, valueType type, const xmlChar* value) {
-	xmlTextWriterWriteAttribute(writer, VALUE_TYPE, (const xmlChar*) valueTypeToString(type));
-	xmlTextWriterWriteAttribute(writer, VALUE, value);
-
-	return CELIX_SUCCESS;
-}
-
-static celix_status_t endpointDescriptorWriter_writeUntypedValue(xmlTextWriterPtr writer, const xmlChar* value) {
-	xmlTextWriterWriteAttribute(writer, VALUE, value);
-
-	return CELIX_SUCCESS;
-}
-
-static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    if (endpoint == NULL || writer == NULL) {
-        status = CELIX_ILLEGAL_ARGUMENT;
-    } else {
-        xmlTextWriterStartElement(writer->writer, ENDPOINT_DESCRIPTION);
-
-        hash_map_iterator_pt iter = hashMapIterator_create(endpoint->properties);
-        while (hashMapIterator_hasNext(iter)) {
-            hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
-            void* propertyName = hashMapEntry_getKey(entry);
-			const xmlChar* propertyValue = (const xmlChar*) hashMapEntry_getValue(entry);
-
-            xmlTextWriterStartElement(writer->writer, PROPERTY);
-            xmlTextWriterWriteAttribute(writer->writer, NAME, propertyName);
-
-            if (strcmp(OSGI_FRAMEWORK_OBJECTCLASS, (char*) propertyName) == 0) {
-            	// objectClass *must* be represented as array of string values...
-            	endpointDescriptorWriter_writeArrayValue(writer->writer, propertyValue);
-            } else if (strcmp(OSGI_RSA_ENDPOINT_SERVICE_ID, (char*) propertyName) == 0) {
-            	// endpoint.service.id *must* be represented as long value...
-            	endpointDescriptorWriter_writeTypedValue(writer->writer, VALUE_TYPE_LONG, propertyValue);
-            } else {
-            	// represent all other values as plain string values...
-            	endpointDescriptorWriter_writeUntypedValue(writer->writer, propertyValue);
-            }
-
-            xmlTextWriterEndElement(writer->writer);
-        }
-        hashMapIterator_destroy(iter);
-
-        xmlTextWriterEndElement(writer->writer);
-    }
-
-    return status;
-}
-
-
-static char* valueTypeToString(valueType type) {
-	switch (type) {
-		case VALUE_TYPE_BOOLEAN:
-			return "boolean";
-		case VALUE_TYPE_BYTE:
-			return "byte";
-		case VALUE_TYPE_CHAR:
-			return "char";
-		case VALUE_TYPE_DOUBLE:
-			return "double";
-		case VALUE_TYPE_FLOAT:
-			return "float";
-		case VALUE_TYPE_INTEGER:
-			return "int";
-		case VALUE_TYPE_LONG:
-			return "long";
-		case VALUE_TYPE_SHORT:
-			return "short";
-		case VALUE_TYPE_STRING:
-			// FALL-THROUGH!
-		default:
-			return "string";
-	}
-}
-
-#ifdef RSA_ENDPOINT_TEST_WRITER
-int main() {
-    endpoint_descriptor_writer_pt writer = NULL;
-    endpointDescriptorWriter_create(&writer);
-    array_list_pt list = NULL;
-    arrayList_create(&list);
-
-    properties_pt props = properties_create();
-    properties_set(props, "objectClass", "com.acme.Foo");
-    properties_set(props, "endpoint.service.id", "3");
-    properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
-    properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
-    endpoint_description_pt epd = NULL;
-    endpointDescription_create(props, &epd);
-    arrayList_add(list, epd);
-
-    properties_pt props2 = properties_create();
-    properties_set(props2, "objectClass", "com.acme.Bar");
-    properties_set(props, "endpoint.service.id", "4");
-    properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
-    properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
-    endpoint_description_pt epd2 = NULL;
-    endpointDescription_create(props2, &epd2);
-    arrayList_add(list, epd2);
-
-    char *buffer = NULL;
-    endpointDescriptorWriter_writeDocument(writer, list, &buffer);
-
-    arrayList_destroy(list);
-    endpointDescription_destroy(epd);
-    endpointDescription_destroy(epd2);
-    endpointDescriptorWriter_destroy(writer);
-
-    printf("%s\n", buffer);
-}
-#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_discovery_poller.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/endpoint_discovery_poller.c b/remote_services/discovery/private/src/endpoint_discovery_poller.c
deleted file mode 100644
index 73fb7ba..0000000
--- a/remote_services/discovery/private/src/endpoint_discovery_poller.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_discovery_poller.c
- *
- * \date       3 Jul 2014
- * \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright  Apache License, Version 2.0
- */
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <curl/curl.h>
-
-#include "bundle_context.h"
-#include "log_helper.h"
-#include "utils.h"
-
-#include "discovery_impl.h"
-
-#include "endpoint_descriptor_reader.h"
-
-
-#define DISCOVERY_POLL_INTERVAL "DISCOVERY_CFG_POLL_INTERVAL"
-#define DEFAULT_POLL_INTERVAL "10"
-
-
-static void *endpointDiscoveryPoller_performPeriodicPoll(void *data);
-celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints);
-static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints);
-static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals);
-
-/**
- * Allocates memory and initializes a new endpoint_discovery_poller instance.
- */
-celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller) {
-	celix_status_t status;
-
-	*poller = malloc(sizeof(struct endpoint_discovery_poller));
-	if (!*poller) {
-		return CELIX_ENOMEM;
-	}
-
-	(*poller)->loghelper = &discovery->loghelper;
-
-	status = celixThreadMutex_create(&(*poller)->pollerLock, NULL);
-	if (status != CELIX_SUCCESS) {
-		return status;
-	}
-
-	const char* interval = NULL;
-	status = bundleContext_getProperty(context, DISCOVERY_POLL_INTERVAL, &interval);
-	if (!interval) {
-		interval = DEFAULT_POLL_INTERVAL;
-	}
-
-	const char* endpointsProp = NULL;
-	status = bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS, &endpointsProp);
-	if (!endpointsProp) {
-		endpointsProp = DEFAULT_POLL_ENDPOINTS;
-	}
-	// we're going to mutate the string with strtok, so create a copy...
-	char* endpoints = strdup(endpointsProp);
-
-	(*poller)->poll_interval = atoi(interval);
-	(*poller)->discovery = discovery;
-	(*poller)->running = false;
-	(*poller)->entries = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-	const char* sep = ",";
-	char *save_ptr = NULL;
-	char* tok = strtok_r(endpoints, sep, &save_ptr);
-	while (tok) {
-		endpointDiscoveryPoller_addDiscoveryEndpoint(*poller, utils_stringTrim(tok));
-		tok = strtok_r(NULL, sep, &save_ptr);
-	}
-	// Clean up after ourselves...
-	free(endpoints);
-
-	status = celixThreadMutex_lock(&(*poller)->pollerLock);
-	if (status != CELIX_SUCCESS) {
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	(*poller)->running = true;
-
-	status += celixThread_create(&(*poller)->pollerThread, NULL, endpointDiscoveryPoller_performPeriodicPoll, *poller);
-	status += celixThreadMutex_unlock(&(*poller)->pollerLock);
-
-	if(status != CELIX_SUCCESS){
-		status = CELIX_BUNDLE_EXCEPTION;
-	}
-
-	return status;
-}
-
-/**
- * Destroys and frees up memory for a given endpoint_discovery_poller struct.
- */
-celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller) {
-	celix_status_t status;
-
-	poller->running = false;
-
-	celixThread_join(poller->pollerThread, NULL);
-
-	hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
-	while (hashMapIterator_hasNext(iterator)) {
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
-
-		if ( endpointDiscoveryPoller_removeDiscoveryEndpoint(poller, (char*) hashMapEntry_getKey(entry)) == CELIX_SUCCESS) {
-			hashMapIterator_destroy(iterator);
-			iterator = hashMapIterator_create(poller->entries);
-		}
-	}
-	hashMapIterator_destroy(iterator);
-
-	status = celixThreadMutex_lock(&poller->pollerLock);
-
-	if (status != CELIX_SUCCESS) {
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	hashMap_destroy(poller->entries, true, false);
-
-	status = celixThreadMutex_unlock(&poller->pollerLock);
-
-	poller->loghelper = NULL;
-
-	free(poller);
-
-	return status;
-}
-
-
-celix_status_t endpointDiscoveryPoller_getDiscoveryEndpoints(endpoint_discovery_poller_pt poller, array_list_pt urls) {
-	celixThreadMutex_lock(&(poller)->pollerLock);
-
-	hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
-
-	while(hashMapIterator_hasNext(iterator))  {
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
-		char* toAdd = strdup((char*) hashMapEntry_getKey(entry));
-		arrayList_add(urls, toAdd);
-	}
-
-	hashMapIterator_destroy(iterator);
-
-	celixThreadMutex_unlock(&(poller)->pollerLock);
-
-	return CELIX_SUCCESS;
-}
-
-/**
- * Adds a new endpoint URL to the list of polled endpoints.
- */
-celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&(poller)->pollerLock);
-	if (status != CELIX_SUCCESS) {
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	// Avoid memory leaks when adding an already existing URL...
-	array_list_pt endpoints = hashMap_get(poller->entries, url);
-	if (endpoints == NULL) {
-		status = arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &endpoints);
-
-		if (status == CELIX_SUCCESS) {
-			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: add new discovery endpoint with url %s", url);
-			hashMap_put(poller->entries, strdup(url), endpoints);
-			endpointDiscoveryPoller_poll(poller, url, endpoints);
-		}
-	}
-
-	status = celixThreadMutex_unlock(&poller->pollerLock);
-
-	return status;
-}
-
-/**
- * Removes an endpoint URL from the list of polled endpoints.
- */
-celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (celixThreadMutex_lock(&poller->pollerLock) != CELIX_SUCCESS) {
-		status = CELIX_BUNDLE_EXCEPTION;
-	} else {
-		hash_map_entry_pt entry = hashMap_getEntry(poller->entries, url);
-
-		if (entry == NULL) {
-			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: There was no entry found belonging to url %s - maybe already removed?", url);
-		} else {
-			char* origKey = hashMapEntry_getKey(entry);
-
-			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: remove discovery endpoint with url %s", url);
-
-			array_list_pt entries = hashMap_remove(poller->entries, url);
-
-			if (entries != NULL) {
-				for (unsigned int i = arrayList_size(entries); i > 0; i--) {
-					endpoint_description_pt endpoint = arrayList_get(entries, i - 1);
-					discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
-					arrayList_remove(entries, i - 1);
-					endpointDescription_destroy(endpoint);
-				}
-				arrayList_destroy(entries);
-			}
-
-			free(origKey);
-		}
-		status = celixThreadMutex_unlock(&poller->pollerLock);
-	}
-
-	return status;
-}
-
-
-
-
-celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints) {
-	celix_status_t status;
-	array_list_pt updatedEndpoints = NULL;
-
-	// create an arraylist with a custom equality test to ensure we can find endpoints properly...
-	arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &updatedEndpoints);
-	status = endpointDiscoveryPoller_getEndpoints(poller, url, &updatedEndpoints);
-
-	if (status == CELIX_SUCCESS) {
-		if (updatedEndpoints!=NULL) {
-			for (unsigned int i = arrayList_size(currentEndpoints); i > 0; i--) {
-				endpoint_description_pt endpoint = arrayList_get(currentEndpoints, i - 1);
-
-				if (!arrayList_contains(updatedEndpoints, endpoint)) {
-					status = discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
-					arrayList_remove(currentEndpoints, i - 1);
-					endpointDescription_destroy(endpoint);
-				}
-			}
-
-			for (int i = arrayList_size(updatedEndpoints); i > 0; i--) {
-				endpoint_description_pt endpoint = arrayList_remove(updatedEndpoints, 0);
-
-				if (!arrayList_contains(currentEndpoints, endpoint)) {
-					arrayList_add(currentEndpoints, endpoint);
-					status = discovery_addDiscoveredEndpoint(poller->discovery, endpoint);
-				} else {
-					endpointDescription_destroy(endpoint);
-
-				}
-			}
-		}
-	}
-
-	if(updatedEndpoints!=NULL){
-		arrayList_destroy(updatedEndpoints);
-	}
-
-	return status;
-}
-
-static void *endpointDiscoveryPoller_performPeriodicPoll(void *data) {
-	endpoint_discovery_poller_pt poller = (endpoint_discovery_poller_pt) data;
-
-	useconds_t interval = (useconds_t) (poller->poll_interval * 1000000L);
-
-	while (poller->running) {
-		usleep(interval);
-		celix_status_t status = celixThreadMutex_lock(&poller->pollerLock);
-
-		if (status != CELIX_SUCCESS) {
-			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to obtain lock; retrying...");
-		} else {
-			hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
-
-			while (hashMapIterator_hasNext(iterator)) {
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
-
-				char *url = hashMapEntry_getKey(entry);
-				array_list_pt currentEndpoints = hashMapEntry_getValue(entry);
-
-				endpointDiscoveryPoller_poll(poller, url, currentEndpoints);
-			}
-
-			hashMapIterator_destroy(iterator);
-		}
-
-		status = celixThreadMutex_unlock(&poller->pollerLock);
-		if (status != CELIX_SUCCESS) {
-			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to release lock; retrying...");
-		}
-	}
-
-	return NULL;
-}
-
-
-
-struct MemoryStruct {
-	char *memory;
-	size_t size;
-};
-
-static size_t endpointDiscoveryPoller_writeMemory(void *contents, size_t size, size_t nmemb, void *memoryPtr) {
-	size_t realsize = size * nmemb;
-	struct MemoryStruct *mem = (struct MemoryStruct *)memoryPtr;
-
-	mem->memory = realloc(mem->memory, mem->size + realsize + 1);
-	if(mem->memory == NULL) {
-		printf("ENDPOINT_POLLER: not enough memory (realloc returned NULL)!");
-		return 0;
-	}
-
-	memcpy(&(mem->memory[mem->size]), contents, realsize);
-	mem->size += realsize;
-	mem->memory[mem->size] = 0;
-
-	return realsize;
-}
-
-static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints) {
-	celix_status_t status = CELIX_SUCCESS;
-
-
-	CURL *curl = NULL;
-	CURLcode res = CURLE_OK;
-
-	struct MemoryStruct chunk;
-	chunk.memory = malloc(1);
-	chunk.size = 0;
-
-	curl = curl_easy_init();
-	if (!curl) {
-		status = CELIX_ILLEGAL_STATE;
-	} else {
-		curl_easy_setopt(curl, CURLOPT_URL, url);
-		curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
-		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, endpointDiscoveryPoller_writeMemory);
-		curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
-		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L);
-		curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
-		res = curl_easy_perform(curl);
-
-		curl_easy_cleanup(curl);
-	}
-
-	// process endpoints file
-	if (res == CURLE_OK) {
-		endpoint_descriptor_reader_pt reader = NULL;
-
-		status = endpointDescriptorReader_create(poller, &reader);
-		if (status == CELIX_SUCCESS) {
-			status = endpointDescriptorReader_parseDocument(reader, chunk.memory, updatedEndpoints);
-		}
-
-		if (reader) {
-			endpointDescriptorReader_destroy(reader);
-		}
-	} else {
-		logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_ERROR, "ENDPOINT_POLLER: unable to read endpoints from %s, reason: %s", url, curl_easy_strerror(res));
-	}
-
-	// clean up endpoints file
-	if (chunk.memory) {
-		free(chunk.memory);
-	}
-
-	return status;
-}
-
-static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals) {
-	endpoint_description_pt endpoint = (endpoint_description_pt) endpointPtr;
-	endpoint_description_pt compare = (endpoint_description_pt) comparePtr;
-
-	if (strcmp(endpoint->id, compare->id) == 0) {
-		*equals = true;
-	} else {
-		*equals = false;
-	}
-
-	return CELIX_SUCCESS;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_discovery_server.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/endpoint_discovery_server.c b/remote_services/discovery/private/src/endpoint_discovery_server.c
deleted file mode 100644
index f5f82af..0000000
--- a/remote_services/discovery/private/src/endpoint_discovery_server.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_discovery_server.c
- *
- * \date		Aug 12, 2014
- * \author		<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright	Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#ifndef ANDROID
-#include <ifaddrs.h>
-#endif
-#include "civetweb.h"
-#include "celix_errno.h"
-#include "utils.h"
-#include "log_helper.h"
-#include "discovery.h"
-#include "discovery_impl.h"
-
-#include "endpoint_descriptor_writer.h"
-
-// defines how often the webserver is restarted (with an increased port number)
-#define MAX_NUMBER_OF_RESTARTS 	15
-#define DEFAULT_SERVER_THREADS "1"
-
-#define CIVETWEB_REQUEST_NOT_HANDLED 0
-#define CIVETWEB_REQUEST_HANDLED 1
-
-static const char *response_headers =
-		"HTTP/1.1 200 OK\r\n"
-		"Cache: no-cache\r\n"
-		"Content-Type: application/xml;charset=utf-8\r\n"
-		"\r\n";
-
-struct endpoint_discovery_server {
-	log_helper_pt* loghelper;
-	hash_map_pt entries; // key = endpointId, value = endpoint_descriptor_pt
-
-	celix_thread_mutex_t serverLock;
-
-	const char* path;
-	const char *port;
-	const char* ip;
-	struct mg_context* ctx;
-};
-
-// Forward declarations...
-static int endpointDiscoveryServer_callback(struct mg_connection *conn);
-static char* format_path(const char* path);
-
-#ifndef ANDROID
-static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip);
-#endif
-
-celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server) {
-	celix_status_t status;
-
-	const char *port = NULL;
-	const char *ip = NULL;
-	char *detectedIp = NULL;
-	const char *path = NULL;
-	const char *retries = NULL;
-
-	int max_ep_num = MAX_NUMBER_OF_RESTARTS;
-
-	*server = malloc(sizeof(struct endpoint_discovery_server));
-	if (!*server) {
-		return CELIX_ENOMEM;
-	}
-
-	(*server)->loghelper = &discovery->loghelper;
-	(*server)->entries = hashMap_create(&utils_stringHash, NULL, &utils_stringEquals, NULL);
-	if (!(*server)->entries) {
-		return CELIX_ENOMEM;
-	}
-
-	status = celixThreadMutex_create(&(*server)->serverLock, NULL);
-	if (status != CELIX_SUCCESS) {
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	bundleContext_getProperty(context, DISCOVERY_SERVER_IP, &ip);
-#ifndef ANDROID
-	if (ip == NULL) {
-		const char *interface = NULL;
-
-		bundleContext_getProperty(context, DISCOVERY_SERVER_INTERFACE, &interface);
-		if ((interface != NULL) && (endpointDiscoveryServer_getIpAdress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
-			logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "Could not retrieve IP adress for interface %s", interface);
-		}
-
-		if (detectedIp == NULL) {
-			endpointDiscoveryServer_getIpAdress(NULL, &detectedIp);
-		}
-
-		ip = detectedIp;
-	}
-#endif
-
-	if (ip != NULL) {
-		logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_INFO, "Using %s for service annunciation", ip);
-		(*server)->ip = strdup(ip);
-	}
-	else {
-		logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "No IP address for service annunciation set. Using %s", DEFAULT_SERVER_IP);
-		(*server)->ip = strdup((char*) DEFAULT_SERVER_IP);
-	}
-
-	if (detectedIp != NULL) {
-		free(detectedIp);
-	}
-
-	bundleContext_getProperty(context, DISCOVERY_SERVER_PORT, &port);
-	if (port == NULL) {
-		port = DEFAULT_SERVER_PORT;
-	}
-
-	bundleContext_getProperty(context, DISCOVERY_SERVER_PATH, &path);
-	if (path == NULL) {
-		path = DEFAULT_SERVER_PATH;
-	}
-
-	bundleContext_getProperty(context, DISCOVERY_SERVER_MAX_EP, &retries);
-	if (retries != NULL) {
-		errno=0;
-		max_ep_num = strtol(retries,NULL,10);
-		if(errno!=0 || max_ep_num<=0){
-			max_ep_num=MAX_NUMBER_OF_RESTARTS;
-		}
-	}
-
-	(*server)->path = format_path(path);
-
-	const struct mg_callbacks callbacks = {
-			.begin_request = endpointDiscoveryServer_callback,
-	};
-
-	unsigned int port_counter = 0;
-	char newPort[10];
-
-	do {
-		const char *options[] = {
-				"listening_ports", port,
-				"num_threads", DEFAULT_SERVER_THREADS,
-				NULL
-		};
-
-		(*server)->ctx = mg_start(&callbacks, (*server), options);
-
-		if ((*server)->ctx != NULL)
-		{
-			logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Starting discovery server on port %s...", port);
-		}
-		else {
-			errno = 0;
-			char* endptr = (char*)port;
-			long currentPort = strtol(port, &endptr, 10);
-
-			if (*endptr || errno != 0) {
-				currentPort = strtol(DEFAULT_SERVER_PORT, NULL, 10);
-			}
-
-			port_counter++;
-			snprintf(&newPort[0], 10,  "%ld", (currentPort+1));
-
-			logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting discovery server on port %s - retrying on port %s...", port, newPort);
-			port = newPort;
-
-		}
-
-	} while(((*server)->ctx == NULL) && (port_counter < max_ep_num));
-
-	(*server)->port = strdup(port);
-
-	return status;
-}
-
-celix_status_t endpointDiscoveryServer_getUrl(endpoint_discovery_server_pt server, char* url)
-{
-	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
-	if (server->ip && server->port && server->path) {
-		sprintf(url, "http://%s:%s/%s", server->ip, server->port, server->path);
-		status = CELIX_SUCCESS;
-	}
-
-	return status;
-}
-
-celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt server) {
-	celix_status_t status;
-
-	// stop & block until the actual server is shut down...
-	if (server->ctx != NULL) {
-		mg_stop(server->ctx);
-		server->ctx = NULL;
-	}
-
-	status = celixThreadMutex_lock(&server->serverLock);
-
-	hashMap_destroy(server->entries, true /* freeKeys */, false /* freeValues */);
-
-	status = celixThreadMutex_unlock(&server->serverLock);
-	status = celixThreadMutex_destroy(&server->serverLock);
-
-	free((void*) server->path);
-	free((void*) server->port);
-	free((void*) server->ip);
-
-	free(server);
-
-	return status;
-}
-
-celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&server->serverLock);
-	if (status != CELIX_SUCCESS) {
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	// create a local copy of the endpointId which we can control...
-	char* endpointId = strdup(endpoint->id);
-	endpoint_description_pt cur_value = hashMap_get(server->entries, endpointId);
-	if (!cur_value) {
-		logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "exposing new endpoint \"%s\"...", endpointId);
-
-		hashMap_put(server->entries, endpointId, endpoint);
-	}
-
-	status = celixThreadMutex_unlock(&server->serverLock);
-	if (status != CELIX_SUCCESS) {
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	return status;
-}
-
-celix_status_t endpointDiscoveryServer_removeEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&server->serverLock);
-	if (status != CELIX_SUCCESS) {
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	hash_map_entry_pt entry = hashMap_getEntry(server->entries, endpoint->id);
-	if (entry) {
-		char* key = hashMapEntry_getKey(entry);
-
-		logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "removing endpoint \"%s\"...\n", key);
-
-		hashMap_remove(server->entries, key);
-
-		// we've made this key, see _addEnpoint above...
-		free((void*) key);
-	}
-
-	status = celixThreadMutex_unlock(&server->serverLock);
-	if (status != CELIX_SUCCESS) {
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	return status;
-}
-
-static char* format_path(const char* path) {
-	char* result = strdup(path);
-	result = utils_stringTrim(result);
-	// check whether the path starts with a leading slash...
-	if (result[0] != '/') {
-		size_t len = strlen(result);
-		result = realloc(result, len + 2);
-		memmove(result + 1, result, len);
-		result[0] = '/';
-		result[len + 1] = 0;
-	}
-	return result;
-}
-
-static celix_status_t endpointDiscoveryServer_getEndpoints(endpoint_discovery_server_pt server, const char* the_endpoint_id, array_list_pt *endpoints) {
-	celix_status_t status;
-
-	status = arrayList_create(endpoints);
-	if (status != CELIX_SUCCESS) {
-		return CELIX_ENOMEM;
-	}
-
-
-	hash_map_iterator_pt iter = hashMapIterator_create(server->entries);
-	while (hashMapIterator_hasNext(iter)) {
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
-		char* endpoint_id = hashMapEntry_getKey(entry);
-		if (the_endpoint_id == NULL || strcmp(the_endpoint_id, endpoint_id) == 0) {
-			endpoint_description_pt endpoint = hashMapEntry_getValue(entry);
-
-			arrayList_add(*endpoints, endpoint);
-		}
-	}
-	hashMapIterator_destroy(iter);
-
-	return status;
-}
-
-static int endpointDiscoveryServer_writeEndpoints(struct mg_connection* conn, array_list_pt endpoints) {
-	celix_status_t status;
-	int rv = CIVETWEB_REQUEST_NOT_HANDLED;
-
-	endpoint_descriptor_writer_pt writer = NULL;
-	status = endpointDescriptorWriter_create(&writer);
-	if (status == CELIX_SUCCESS) {
-
-		char *buffer = NULL;
-		status = endpointDescriptorWriter_writeDocument(writer, endpoints, &buffer);
-		if (buffer) {
-			mg_write(conn, response_headers, strlen(response_headers));
-			mg_write(conn, buffer, strlen(buffer));
-		}
-
-		rv = CIVETWEB_REQUEST_HANDLED;
-	}
-
-	if(writer!=NULL){
-		endpointDescriptorWriter_destroy(writer);
-	}
-
-	return rv;
-}
-
-// returns all endpoints as XML...
-static int endpointDiscoveryServer_returnAllEndpoints(endpoint_discovery_server_pt server, struct mg_connection* conn) {
-	int status = CIVETWEB_REQUEST_NOT_HANDLED;
-
-	array_list_pt endpoints = NULL;
-
-	if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) {
-		endpointDiscoveryServer_getEndpoints(server, NULL, &endpoints);
-		if (endpoints) {
-			status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
-
-			arrayList_destroy(endpoints);
-		}
-
-
-		celixThreadMutex_unlock(&server->serverLock);
-	}
-
-	return status;
-}
-
-// returns a single endpoint as XML...
-static int endpointDiscoveryServer_returnEndpoint(endpoint_discovery_server_pt server, struct mg_connection* conn, const char* endpoint_id) {
-	int status = CIVETWEB_REQUEST_NOT_HANDLED;
-
-	array_list_pt endpoints = NULL;
-
-	if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) {
-		endpointDiscoveryServer_getEndpoints(server, endpoint_id, &endpoints);
-		if (endpoints) {
-			status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
-
-			arrayList_destroy(endpoints);
-		}
-
-		celixThreadMutex_unlock(&server->serverLock);
-	}
-
-	return status;
-}
-
-static int endpointDiscoveryServer_callback(struct mg_connection* conn) {
-	int status = CIVETWEB_REQUEST_NOT_HANDLED;
-
-	const struct mg_request_info *request_info = mg_get_request_info(conn);
-	if (request_info->uri != NULL && strcmp("GET", request_info->request_method) == 0) {
-		endpoint_discovery_server_pt server = request_info->user_data;
-
-		const char *uri = request_info->uri;
-		const size_t path_len = strlen(server->path);
-		const size_t uri_len = strlen(uri);
-
-		if (strncmp(server->path, uri, strlen(server->path)) == 0) {
-			// Be lenient when it comes to the trailing slash...
-			if (path_len == uri_len || (uri_len == (path_len + 1) && uri[path_len] == '/')) {
-				status = endpointDiscoveryServer_returnAllEndpoints(server, conn);
-			} else {
-				const char* endpoint_id = uri + path_len + 1; // right after the slash...
-
-				status = endpointDiscoveryServer_returnEndpoint(server, conn, endpoint_id);
-			}
-		}
-	}
-
-	return status;
-}
-
-#ifndef ANDROID
-static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip) {
-	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
-	struct ifaddrs *ifaddr, *ifa;
-	char host[NI_MAXHOST];
-
-	if (getifaddrs(&ifaddr) != -1)
-	{
-		for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
-		{
-			if (ifa->ifa_addr == NULL)
-				continue;
-
-			if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
-				if (interface == NULL) {
-					*ip = strdup(host);
-					status = CELIX_SUCCESS;
-				}
-				else if (strcmp(ifa->ifa_name, interface) == 0) {
-					*ip = strdup(host);
-					status = CELIX_SUCCESS;
-				}
-			}
-		}
-
-		freeifaddrs(ifaddr);
-	}
-
-	return status;
-}
-#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/CMakeLists.txt b/remote_services/discovery_common/CMakeLists.txt
new file mode 100644
index 0000000..9388c90
--- /dev/null
+++ b/remote_services/discovery_common/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+find_package(LibXml2 REQUIRED)
+
+add_library(discovery_common STATIC
+		src/discovery.c
+		src/discovery_activator.c
+		src/endpoint_descriptor_reader.c
+		src/endpoint_descriptor_writer.c
+		src/endpoint_discovery_poller.c
+		src/endpoint_discovery_server.c
+        src/civetweb.c
+)
+target_include_directories(discovery_common PUBLIC include)
+target_include_directories(discovery_common PRIVATE src ${LIBXML2_INCLUDE_DIR})
+target_link_libraries(discovery_common PRIVATE ${LIBXML2_LIBRARIES} Celix::framework)
+target_link_libraries(discovery_common PUBLIC Celix::log_helper Celix::remote_service_admin_api)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/civetweb.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/civetweb.h b/remote_services/discovery_common/include/civetweb.h
new file mode 100644
index 0000000..61a8e98
--- /dev/null
+++ b/remote_services/discovery_common/include/civetweb.h
@@ -0,0 +1,657 @@
+/* Copyright (c) 2013-2014 the Civetweb developers
+ * Copyright (c) 2004-2013 Sergey Lyubka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef CIVETWEB_HEADER_INCLUDED
+#define CIVETWEB_HEADER_INCLUDED
+
+#ifndef CIVETWEB_VERSION
+#define CIVETWEB_VERSION "1.7"
+#endif
+
+#ifndef CIVETWEB_API
+    #if defined(_WIN32)
+        #if defined(CIVETWEB_DLL_EXPORTS)
+            #define CIVETWEB_API __declspec(dllexport)
+        #elif defined(CIVETWEB_DLL_IMPORTS)
+            #define CIVETWEB_API __declspec(dllimport)
+        #else
+            #define CIVETWEB_API
+        #endif
+    #else
+        #define CIVETWEB_API
+    #endif
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct mg_context;     /* Handle for the HTTP service itself */
+struct mg_connection;  /* Handle for the individual connection */
+
+
+/* This structure contains information about the HTTP request. */
+struct mg_request_info {
+    const char *request_method; /* "GET", "POST", etc */
+    const char *uri;            /* URL-decoded URI */
+    const char *http_version;   /* E.g. "1.0", "1.1" */
+    const char *query_string;   /* URL part after '?', not including '?', or
+                                   NULL */
+    const char *remote_user;    /* Authenticated user, or NULL if no auth
+                                   used */
+    char remote_addr[48];       /* Client's IP address as a string. */
+    long remote_ip;             /* Client's IP address. Deprecated: use remote_addr instead */
+
+    long long content_length;   /* Length (in bytes) of the request body,
+                                   can be -1 if no length was given. */
+    int remote_port;            /* Client's port */
+    int is_ssl;                 /* 1 if SSL-ed, 0 if not */
+    void *user_data;            /* User data pointer passed to mg_start() */
+    void *conn_data;            /* Connection-specific user data */
+
+    int num_headers;            /* Number of HTTP headers */
+    struct mg_header {
+        const char *name;       /* HTTP header name */
+        const char *value;      /* HTTP header value */
+    } http_headers[64];         /* Maximum 64 headers */
+};
+
+
+/* This structure needs to be passed to mg_start(), to let civetweb know
+   which callbacks to invoke. For a detailed description, see
+   https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md */
+struct mg_callbacks {
+    /* Called when civetweb has received new HTTP request.
+       If the callback returns one, it must process the request
+       by sending valid HTTP headers and a body. Civetweb will not do
+       any further processing. Otherwise it must return zero.
+       Note that since V1.7 the "begin_request" function is called
+       before an authorization check. If an authorization check is
+       required, use a request_handler instead.
+       Return value:
+         0: civetweb will process the request itself. In this case,
+            the callback must not send any data to the client.
+         1: callback already processed the request. Civetweb will
+            not send any data after the callback returned. */
+    int  (*begin_request)(struct mg_connection *);
+
+    /* Called when civetweb has finished processing request. */
+    void (*end_request)(const struct mg_connection *, int reply_status_code);
+
+    /* Called when civetweb is about to log a message. If callback returns
+       non-zero, civetweb does not log anything. */
+    int  (*log_message)(const struct mg_connection *, const char *message);
+
+    /* Called when civetweb initializes SSL library.
+       Parameters:
+         user_data: parameter user_data passed when starting the server.
+       Return value:
+         0: civetweb will set up the SSL certificate.
+         1: civetweb assumes the callback already set up the certificate.
+        -1: initializing ssl fails. */
+    int  (*init_ssl)(void *ssl_context, void *user_data);
+
+    /* Called when websocket request is received, before websocket handshake.
+       Return value:
+         0: civetweb proceeds with websocket handshake.
+         1: connection is closed immediately. */
+    int (*websocket_connect)(const struct mg_connection *);
+
+    /* Called when websocket handshake is successfully completed, and
+       connection is ready for data exchange. */
+    void (*websocket_ready)(struct mg_connection *);
+
+    /* Called when data frame has been received from the client.
+       Parameters:
+         bits: first byte of the websocket frame, see websocket RFC at
+               http://tools.ietf.org/html/rfc6455, section 5.2
+         data, data_len: payload, with mask (if any) already applied.
+       Return value:
+         1: keep this websocket connection open.
+         0: close this websocket connection. */
+    int  (*websocket_data)(struct mg_connection *, int bits,
+                           char *data, size_t data_len);
+
+    /* Called when civetweb is closing a connection.  The per-context mutex is
+       locked when this is invoked.  This is primarily useful for noting when
+       a websocket is closing and removing it from any application-maintained
+       list of clients. */
+    void (*connection_close)(struct mg_connection *);
+
+    /* Called when civetweb tries to open a file. Used to intercept file open
+       calls, and serve file data from memory instead.
+       Parameters:
+          path:     Full path to the file to open.
+          data_len: Placeholder for the file size, if file is served from
+                    memory.
+       Return value:
+         NULL: do not serve file from memory, proceed with normal file open.
+         non-NULL: pointer to the file contents in memory. data_len must be
+           initilized with the size of the memory block. */
+    const char * (*open_file)(const struct mg_connection *,
+                              const char *path, size_t *data_len);
+
+    /* Called when civetweb is about to serve Lua server page, if
+       Lua support is enabled.
+       Parameters:
+         lua_context: "lua_State *" pointer. */
+    void (*init_lua)(struct mg_connection *, void *lua_context);
+
+    /* Called when civetweb has uploaded a file to a temporary directory as a
+       result of mg_upload() call.
+       Parameters:
+         file_name: full path name to the uploaded file. */
+    void (*upload)(struct mg_connection *, const char *file_name);
+
+    /* Called when civetweb is about to send HTTP error to the client.
+       Implementing this callback allows to create custom error pages.
+       Parameters:
+         status: HTTP error status code.
+       Return value:
+         1: run civetweb error handler.
+         0: callback already handled the error. */
+    int  (*http_error)(struct mg_connection *, int status);
+
+    /* Called after civetweb context has been created, before requests
+       are processed.
+       Parameters:
+         ctx: context handle */
+    void (*init_context)(struct mg_context * ctx);
+
+    /* Called when civetweb context is deleted.
+       Parameters:
+         ctx: context handle */
+    void (*exit_context)(struct mg_context * ctx);
+};
+
+
+/* Start web server.
+
+   Parameters:
+     callbacks: mg_callbacks structure with user-defined callbacks.
+     options: NULL terminated list of option_name, option_value pairs that
+              specify Civetweb configuration parameters.
+
+   Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
+      processing is required for these, signal handlers must be set up
+      after calling mg_start().
+
+
+   Example:
+     const char *options[] = {
+       "document_root", "/var/www",
+       "listening_ports", "80,443s",
+       NULL
+     };
+     struct mg_context *ctx = mg_start(&my_func, NULL, options);
+
+   Refer to https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md
+   for the list of valid option and their possible values.
+
+   Return:
+     web server context, or NULL on error. */
+CIVETWEB_API struct mg_context *mg_start(const struct mg_callbacks *callbacks,
+                            void *user_data,
+                            const char **configuration_options);
+
+
+/* Stop the web server.
+
+   Must be called last, when an application wants to stop the web server and
+   release all associated resources. This function blocks until all Civetweb
+   threads are stopped. Context pointer becomes invalid. */
+CIVETWEB_API void mg_stop(struct mg_context *);
+
+
+/* mg_request_handler
+
+   Called when a new request comes in.  This callback is URI based
+   and configured with mg_set_request_handler().
+
+   Parameters:
+      conn: current connection information.
+      cbdata: the callback data configured with mg_set_request_handler().
+   Returns:
+      0: the handler could not handle the request, so fall through.
+      1: the handler processed the request. */
+typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata);
+
+
+/* mg_set_request_handler
+
+   Sets or removes a URI mapping for a request handler.
+
+   URI's are ordered and prefixed URI's are supported. For example,
+   consider two URIs: /a/b and /a
+           /a   matches /a
+           /a/b matches /a/b
+           /a/c matches /a
+
+   Parameters:
+      ctx: server context
+      uri: the URI to configure
+      handler: the callback handler to use when the URI is requested.
+               If NULL, the URI will be removed.
+      cbdata: the callback data to give to the handler when it s requested. */
+CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata);
+
+
+/* Get the value of particular configuration parameter.
+   The value returned is read-only. Civetweb does not allow changing
+   configuration at run time.
+   If given parameter name is not valid, NULL is returned. For valid
+   names, return value is guaranteed to be non-NULL. If parameter is not
+   set, zero-length string is returned. */
+CIVETWEB_API const char *mg_get_option(const struct mg_context *ctx, const char *name);
+
+
+/* Get context from connection. */
+CIVETWEB_API struct mg_context *mg_get_context(struct mg_connection *conn);
+
+
+/* Get user data passed to mg_start from context. */
+CIVETWEB_API void *mg_get_user_data(struct mg_context *ctx);
+
+
+#if defined(MG_LEGACY_INTERFACE)
+/* Return array of strings that represent valid configuration options.
+   For each option, option name and default value is returned, i.e. the
+   number of entries in the array equals to number_of_options x 2.
+   Array is NULL terminated. */
+/* Deprecated: Use mg_get_valid_options instead. */
+CIVETWEB_API const char **mg_get_valid_option_names(void);
+#endif
+
+
+struct mg_option {
+    const char * name;
+    int type;
+    const char * default_value;
+};
+
+enum {
+    CONFIG_TYPE_UNKNOWN = 0x0,
+    CONFIG_TYPE_NUMBER = 0x1,
+    CONFIG_TYPE_STRING = 0x2,
+    CONFIG_TYPE_FILE = 0x3,
+    CONFIG_TYPE_DIRECTORY = 0x4,
+    CONFIG_TYPE_BOOLEAN = 0x5,
+    CONFIG_TYPE_EXT_PATTERN = 0x6
+};
+
+
+/* Return array of struct mg_option, representing all valid configuration
+   options of civetweb.c.
+   The array is terminated by a NULL name option. */
+CIVETWEB_API const struct mg_option *mg_get_valid_options(void);
+
+
+/* Get the list of ports that civetweb is listening on.
+   size is the size of the ports int array and ssl int array to fill.
+   It is the caller's responsibility to make sure ports and ssl each
+   contain at least size int elements worth of memory to write into.
+   Return value is the number of ports and ssl information filled in.
+   The value returned is read-only. Civetweb does not allow changing
+   configuration at run time. */
+CIVETWEB_API size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl);
+
+
+/* Add, edit or delete the entry in the passwords file.
+
+   This function allows an application to manipulate .htpasswd files on the
+   fly by adding, deleting and changing user records. This is one of the
+   several ways of implementing authentication on the server side. For another,
+   cookie-based way please refer to the examples/chat in the source tree.
+
+   If password is not NULL, entry is added (or modified if already exists).
+   If password is NULL, entry is deleted.
+
+   Return:
+     1 on success, 0 on error. */
+CIVETWEB_API int mg_modify_passwords_file(const char *passwords_file_name,
+                                          const char *domain,
+                                          const char *user,
+                                          const char *password);
+
+
+/* Return information associated with the request. */
+CIVETWEB_API struct mg_request_info *mg_get_request_info(struct mg_connection *);
+
+
+/* Send data to the client.
+   Return:
+    0   when the connection has been closed
+    -1  on error
+    >0  number of bytes written on success */
+CIVETWEB_API int mg_write(struct mg_connection *, const void *buf, size_t len);
+
+
+/* Send data to a websocket client wrapped in a websocket frame.  Uses mg_lock
+   to ensure that the transmission is not interrupted, i.e., when the
+   application is proactively communicating and responding to a request
+   simultaneously.
+
+   Send data to a websocket client wrapped in a websocket frame.
+   This function is available when civetweb is compiled with -DUSE_WEBSOCKET
+
+   Return:
+    0   when the connection has been closed
+    -1  on error
+    >0  number of bytes written on success */
+CIVETWEB_API int mg_websocket_write(struct mg_connection* conn, int opcode,
+                                    const char *data, size_t data_len);
+
+
+/* Blocks until unique access is obtained to this connection. Intended for use
+   with websockets only.
+   Invoke this before mg_write or mg_printf when communicating with a
+   websocket if your code has server-initiated communication as well as
+   communication in direct response to a message. */
+CIVETWEB_API void mg_lock_connection(struct mg_connection* conn);
+CIVETWEB_API void mg_unlock_connection(struct mg_connection* conn);
+
+#if defined(MG_LEGACY_INTERFACE)
+#define mg_lock mg_lock_connection
+#define mg_unlock mg_unlock_connection
+#endif
+
+/* Lock server context.  This lock may be used to protect ressources
+   that are shared between different connection/worker threads. */
+CIVETWEB_API void mg_lock_context(struct mg_context* ctx);
+CIVETWEB_API void mg_unlock_context(struct mg_context* ctx);
+
+
+/* Opcodes, from http://tools.ietf.org/html/rfc6455 */
+enum {
+    WEBSOCKET_OPCODE_CONTINUATION = 0x0,
+    WEBSOCKET_OPCODE_TEXT = 0x1,
+    WEBSOCKET_OPCODE_BINARY = 0x2,
+    WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
+    WEBSOCKET_OPCODE_PING = 0x9,
+    WEBSOCKET_OPCODE_PONG = 0xa
+};
+
+
+/* Macros for enabling compiler-specific checks forprintf-like arguments. */
+#undef PRINTF_FORMAT_STRING
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#include <sal.h>
+#if defined(_MSC_VER) && _MSC_VER > 1400
+#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
+#else
+#define PRINTF_FORMAT_STRING(s) __format_string s
+#endif
+#else
+#define PRINTF_FORMAT_STRING(s) s
+#endif
+
+#ifdef __GNUC__
+#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
+#else
+#define PRINTF_ARGS(x, y)
+#endif
+
+/* Send data to the client usingprintf() semantics.
+   Works exactly like mg_write(), but allows to do message formatting. */
+CIVETWEB_API int mg_printf(struct mg_connection *,
+                           PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
+
+
+/* Send contents of the entire file together with HTTP headers. */
+CIVETWEB_API void mg_send_file(struct mg_connection *conn, const char *path);
+
+
+/* Read data from the remote end, return number of bytes read.
+   Return:
+     0     connection has been closed by peer. No more data could be read.
+     < 0   read error. No more data could be read from the connection.
+     > 0   number of bytes read into the buffer. */
+CIVETWEB_API int mg_read(struct mg_connection *, void *buf, size_t len);
+
+
+/* Get the value of particular HTTP header.
+
+   This is a helper function. It traverses request_info->http_headers array,
+   and if the header is present in the array, returns its value. If it is
+   not present, NULL is returned. */
+CIVETWEB_API const char *mg_get_header(const struct mg_connection *, const char *name);
+
+
+/* Get a value of particular form variable.
+
+   Parameters:
+     data: pointer to form-uri-encoded buffer. This could be either POST data,
+           or request_info.query_string.
+     data_len: length of the encoded data.
+     var_name: variable name to decode from the buffer
+     dst: destination buffer for the decoded variable
+     dst_len: length of the destination buffer
+
+   Return:
+     On success, length of the decoded variable.
+     On error:
+        -1 (variable not found).
+        -2 (destination buffer is NULL, zero length or too small to hold the
+            decoded variable).
+
+   Destination buffer is guaranteed to be '\0' - terminated if it is not
+   NULL or zero length. */
+CIVETWEB_API int mg_get_var(const char *data, size_t data_len,
+                            const char *var_name, char *dst, size_t dst_len);
+
+
+/* Get a value of particular form variable.
+
+   Parameters:
+     data: pointer to form-uri-encoded buffer. This could be either POST data,
+           or request_info.query_string.
+     data_len: length of the encoded data.
+     var_name: variable name to decode from the buffer
+     dst: destination buffer for the decoded variable
+     dst_len: length of the destination buffer
+     occurrence: which occurrence of the variable, 0 is the first, 1 the
+                 second...
+                this makes it possible to parse a query like
+                b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
+
+   Return:
+     On success, length of the decoded variable.
+     On error:
+        -1 (variable not found).
+        -2 (destination buffer is NULL, zero length or too small to hold the
+            decoded variable).
+
+   Destination buffer is guaranteed to be '\0' - terminated if it is not
+   NULL or zero length. */
+CIVETWEB_API int mg_get_var2(const char *data, size_t data_len,
+                             const char *var_name, char *dst, size_t dst_len, size_t occurrence);
+
+
+/* Fetch value of certain cookie variable into the destination buffer.
+
+   Destination buffer is guaranteed to be '\0' - terminated. In case of
+   failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
+   parameter. This function returns only first occurrence.
+
+   Return:
+     On success, value length.
+     On error:
+        -1 (either "Cookie:" header is not present at all or the requested
+            parameter is not found).
+        -2 (destination buffer is NULL, zero length or too small to hold the
+            value). */
+CIVETWEB_API int mg_get_cookie(const char *cookie, const char *var_name,
+                               char *buf, size_t buf_len);
+
+
+/* Download data from the remote web server.
+     host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
+     port: port number, e.g. 80.
+     use_ssl: wether to use SSL connection.
+     error_buffer, error_buffer_size: error message placeholder.
+     request_fmt,...: HTTP request.
+   Return:
+     On success, valid pointer to the new connection, suitable for mg_read().
+     On error, NULL. error_buffer contains error message.
+   Example:
+     char ebuf[100];
+     struct mg_connection *conn;
+     conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
+                        "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
+ */
+CIVETWEB_API struct mg_connection *mg_download(const char *host, int port, int use_ssl,
+                                               char *error_buffer, size_t error_buffer_size,
+                                               PRINTF_FORMAT_STRING(const char *request_fmt),
+                                               ...) PRINTF_ARGS(6, 7);
+
+
+/* Close the connection opened by mg_download(). */
+CIVETWEB_API void mg_close_connection(struct mg_connection *conn);
+
+
+/* File upload functionality. Each uploaded file gets saved into a temporary
+   file and MG_UPLOAD event is sent.
+   Return number of uploaded files. */
+CIVETWEB_API int mg_upload(struct mg_connection *conn, const char *destination_dir);
+
+
+/* Convenience function -- create detached thread.
+   Return: 0 on success, non-0 on error. */
+typedef void * (*mg_thread_func_t)(void *);
+CIVETWEB_API int mg_start_thread(mg_thread_func_t f, void *p);
+
+
+/* Return builtin mime type for the given file name.
+   For unrecognized extensions, "text/plain" is returned. */
+CIVETWEB_API const char *mg_get_builtin_mime_type(const char *file_name);
+
+
+/* Return Civetweb version. */
+CIVETWEB_API const char *mg_version(void);
+
+
+/* URL-decode input buffer into destination buffer.
+   0-terminate the destination buffer.
+   form-url-encoded data differs from URI encoding in a way that it
+   uses '+' as character for space, see RFC 1866 section 8.2.1
+   http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
+   Return: length of the decoded data, or -1 if dst buffer is too small. */
+CIVETWEB_API int mg_url_decode(const char *src, int src_len, char *dst,
+                               int dst_len, int is_form_url_encoded);
+
+
+/* URL-encode input buffer into destination buffer.
+   returns the length of the resulting buffer or -1
+   is the buffer is too small. */
+CIVETWEB_API int mg_url_encode(const char *src, char *dst, size_t dst_len);
+
+
+/* MD5 hash given strings.
+   Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
+   ASCIIz strings. When function returns, buf will contain human-readable
+   MD5 hash. Example:
+     char buf[33];
+     mg_md5(buf, "aa", "bb", NULL); */
+CIVETWEB_API char *mg_md5(char buf[33], ...);
+
+
+/* Print error message to the opened error log stream.
+   This utilizes the provided logging configuration.
+     conn: connection
+     fmt: format string without the line return
+     ...: variable argument list
+   Example:
+     mg_cry(conn,"i like %s", "logging"); */
+CIVETWEB_API void mg_cry(struct mg_connection *conn,
+                         PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
+
+
+/* utility method to compare two buffers, case incensitive. */
+CIVETWEB_API int mg_strncasecmp(const char *s1, const char *s2, size_t len);
+
+/* Connect to a websocket as a client
+   Parameters:
+     host: host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost"
+     port: server port
+     use_ssl: make a secure connection to server
+     error_buffer, error_buffer_size: buffer for an error message
+     path: server path you are trying to connect to, i.e. if connection to localhost/app, path should be "/app"
+     origin: value of the Origin HTTP header
+     data_func: callback that should be used when data is received from the server
+     user_data: user supplied argument
+
+   Return:
+     On success, valid mg_connection object.
+     On error, NULL. Se error_buffer for details.
+*/
+
+typedef int  (*websocket_data_func)(struct mg_connection *, int bits,
+                           char *data, size_t data_len);
+
+typedef void (*websocket_close_func)(struct mg_connection *);
+
+CIVETWEB_API struct mg_connection *mg_connect_websocket_client(const char *host, int port, int use_ssl,
+                                               char *error_buffer, size_t error_buffer_size,
+                                               const char *path, const char *origin,
+                                               websocket_data_func data_func, websocket_close_func close_func,
+                                               void * user_data);
+
+/* Connect to a TCP server as a client (can be used to connect to a HTTP server)
+   Parameters:
+     host: host to connect to, i.e. "www.wikipedia.org" or "192.168.1.1" or "localhost"
+     port: server port
+     use_ssl: make a secure connection to server
+     error_buffer, error_buffer_size: buffer for an error message
+
+   Return:
+     On success, valid mg_connection object.
+     On error, NULL. Se error_buffer for details.
+*/
+CIVETWEB_API struct mg_connection *mg_connect_client(const char *host, int port, int use_ssl,
+                                               char *error_buffer, size_t error_buffer_size);
+
+
+enum {
+    TIMEOUT_INFINITE = -1
+};
+
+/* Wait for a response from the server
+   Parameters:
+     conn: connection
+     ebuf, ebuf_len: error message placeholder.
+     timeout: time to wait for a response in milliseconds (if < 0 then wait forever)
+
+   Return:
+     On success, >= 0
+     On error/timeout, < 0
+*/
+CIVETWEB_API int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CIVETWEB_HEADER_INCLUDED */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/discovery.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/discovery.h b/remote_services/discovery_common/include/discovery.h
new file mode 100644
index 0000000..ee79caf
--- /dev/null
+++ b/remote_services/discovery_common/include/discovery.h
@@ -0,0 +1,67 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * discovery.h
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef DISCOVERY_H_
+#define DISCOVERY_H_
+
+#include "bundle_context.h"
+#include "service_reference.h"
+
+#include "endpoint_description.h"
+#include "endpoint_listener.h"
+
+#define DISCOVERY_SERVER_INTERFACE	"DISCOVERY_CFG_SERVER_INTERFACE"
+#define DISCOVERY_SERVER_IP 		"DISCOVERY_CFG_SERVER_IP"
+#define DISCOVERY_SERVER_PORT 		"DISCOVERY_CFG_SERVER_PORT"
+#define DISCOVERY_SERVER_PATH 		"DISCOVERY_CFG_SERVER_PATH"
+#define DISCOVERY_POLL_ENDPOINTS 	"DISCOVERY_CFG_POLL_ENDPOINTS"
+#define DISCOVERY_SERVER_MAX_EP	"DISCOVERY_CFG_SERVER_MAX_EP"
+
+typedef struct discovery *discovery_pt;
+
+
+/* those one could be put into a general discovery.h - file */
+celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery);
+celix_status_t discovery_destroy(discovery_pt discovery);
+
+celix_status_t discovery_start(discovery_pt discovery);
+celix_status_t discovery_stop(discovery_pt discovery);
+
+celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+
+celix_status_t discovery_endpointListenerAdding(void * handle, service_reference_pt reference, void **service);
+celix_status_t discovery_endpointListenerAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service);
+celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service);
+
+celix_status_t discovery_informEndpointListeners(discovery_pt discovery, endpoint_description_pt endpoint, bool endpointAdded);
+celix_status_t discovery_updateEndpointListener(discovery_pt discovery, service_reference_pt reference, endpoint_listener_pt service);
+
+celix_status_t discovery_addDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint);
+celix_status_t discovery_removeDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint);
+
+#endif /* DISCOVERY_H_ */


[05/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c
new file mode 100644
index 0000000..9feab9f
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c
@@ -0,0 +1,775 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_impl.c
+ *
+ *  \date       May 21, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include <string.h>
+#include <uuid/uuid.h>
+#include <curl/curl.h>
+
+#include <jansson.h>
+#include "json_serializer.h"
+#include "remote_service_admin.h"
+#include "celix_threads.h"
+#include "hash_map.h"
+#include "array_list.h"
+
+#include "import_registration_dfi.h"
+#include "export_registration_dfi.h"
+#include "remote_service_admin_dfi.h"
+#include "dyn_interface.h"
+#include "json_rpc.h"
+
+#include "remote_constants.h"
+#include "constants.h"
+#include "civetweb.h"
+
+// defines how often the webserver is restarted (with an increased port number)
+#define MAX_NUMBER_OF_RESTARTS 	5
+
+
+#define RSA_LOG_ERROR(admin, msg, ...) \
+    logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg),  ##__VA_ARGS__)
+
+#define RSA_LOG_WARNING(admin, msg, ...) \
+    logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg),  ##__VA_ARGS__)
+
+#define RSA_LOG_DEBUG(admin, msg, ...) \
+    logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg),  ##__VA_ARGS__)
+
+struct remote_service_admin {
+    bundle_context_pt context;
+    log_helper_pt loghelper;
+
+    celix_thread_mutex_t exportedServicesLock;
+    hash_map_pt exportedServices;
+
+    celix_thread_mutex_t importedServicesLock;
+    array_list_pt importedServices;
+
+    char *port;
+    char *ip;
+
+    struct mg_context *ctx;
+};
+
+struct post {
+    const char *readptr;
+    int size;
+};
+
+struct get {
+    char *writeptr;
+    int size;
+};
+
+#define OSGI_RSA_REMOTE_PROXY_FACTORY 	"remote_proxy_factory"
+#define OSGI_RSA_REMOTE_PROXY_TIMEOUT   "remote_proxy_timeout"
+
+static const char *data_response_headers =
+        "HTTP/1.1 200 OK\r\n"
+                "Cache: no-cache\r\n"
+                "Content-Type: application/json\r\n"
+                "\r\n";
+
+static const char *no_content_response_headers =
+        "HTTP/1.1 204 OK\r\n";
+
+// TODO do we need to specify a non-Amdatu specific configuration type?!
+static const char * const CONFIGURATION_TYPE = "org.amdatu.remote.admin.http";
+static const char * const ENDPOINT_URL = "org.amdatu.remote.admin.http.url";
+
+static const char *DEFAULT_PORT = "8888";
+static const char *DEFAULT_IP = "127.0.0.1";
+
+static const unsigned int DEFAULT_TIMEOUT = 0;
+
+static int remoteServiceAdmin_callback(struct mg_connection *conn);
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, char *interface, endpoint_description_pt *description);
+static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
+static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip);
+static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp);
+static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp);
+static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...);
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *admin = calloc(1, sizeof(**admin));
+
+    if (!*admin) {
+        status = CELIX_ENOMEM;
+    } else {
+        unsigned int port_counter = 0;
+        const char *port = NULL;
+        const char *ip = NULL;
+        char *detectedIp = NULL;
+        (*admin)->context = context;
+        (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
+         arrayList_create(&(*admin)->importedServices);
+
+        celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
+        celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
+
+        if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
+            logHelper_start((*admin)->loghelper);
+            dynCommon_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+            dynType_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+            dynFunction_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+            dynInterface_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+            jsonSerializer_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+            jsonRpc_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+        }
+
+        bundleContext_getProperty(context, "RSA_PORT", &port);
+        if (port == NULL) {
+            port = (char *)DEFAULT_PORT;
+        }
+
+        bundleContext_getProperty(context, "RSA_IP", &ip);
+        if (ip == NULL) {
+            const char *interface = NULL;
+
+            bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
+            if ((interface != NULL) && (remoteServiceAdmin_getIpAdress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
+                logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Could not retrieve IP adress for interface %s", interface);
+            }
+
+            if (ip == NULL) {
+                remoteServiceAdmin_getIpAdress(NULL, &detectedIp);
+            }
+
+            ip = detectedIp;
+        }
+
+        if (ip != NULL) {
+            logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Using %s for service annunciation", ip);
+            (*admin)->ip = strdup(ip);
+        }
+        else {
+            logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No IP address for service annunciation set. Using %s", DEFAULT_IP);
+            (*admin)->ip = strdup((char*) DEFAULT_IP);
+        }
+
+        if (detectedIp != NULL) {
+            free(detectedIp);
+        }
+
+        // Prepare callbacks structure. We have only one callback, the rest are NULL.
+        struct mg_callbacks callbacks;
+        memset(&callbacks, 0, sizeof(callbacks));
+        callbacks.begin_request = remoteServiceAdmin_callback;
+
+        char newPort[10];
+
+        do {
+
+            const char *options[] = { "listening_ports", port, "num_threads", "5", NULL};
+
+            (*admin)->ctx = mg_start(&callbacks, (*admin), options);
+
+            if ((*admin)->ctx != NULL) {
+                logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Start webserver: %s", port);
+                (*admin)->port = strdup(port);
+
+            }
+            else {
+            	errno = 0;
+                char* endptr = (char*)port;
+                int currentPort = strtol(port, &endptr, 10);
+
+                if (*endptr || errno != 0) {
+                    currentPort = strtol(DEFAULT_PORT, NULL, 10);
+                }
+
+                port_counter++;
+                snprintf(&newPort[0], 6,  "%d", (currentPort+1));
+
+                logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting rsa server on port %s - retrying on port %s...", port, newPort);
+                port = newPort;
+            }
+        } while(((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS));
+
+    }
+
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin)
+{
+    celix_status_t status = CELIX_SUCCESS;
+
+    free((*admin)->ip);
+    free((*admin)->port);
+    free(*admin);
+
+    //TODO destroy exports/imports
+
+    *admin = NULL;
+
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    celixThreadMutex_lock(&admin->exportedServicesLock);
+
+    hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
+    while (hashMapIterator_hasNext(iter)) {
+        array_list_pt exports = hashMapIterator_nextValue(iter);
+        int i;
+        for (i = 0; i < arrayList_size(exports); i++) {
+            export_registration_pt export = arrayList_get(exports, i);
+            if (export != NULL) {
+                exportRegistration_stop(export);
+                exportRegistration_destroy(export);
+            }
+        }
+        arrayList_destroy(exports);
+    }
+    hashMapIterator_destroy(iter);
+    celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+    celixThreadMutex_lock(&admin->importedServicesLock);
+    int i;
+    int size = arrayList_size(admin->importedServices);
+    for (i = 0; i < size ; i += 1) {
+        import_registration_pt import = arrayList_get(admin->importedServices, i);
+        if (import != NULL) {
+            importRegistration_stop(import);
+            importRegistration_destroy(import);
+        }
+    }
+    celixThreadMutex_unlock(&admin->importedServicesLock);
+
+    if (admin->ctx != NULL) {
+        logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Stopping webserver...");
+        mg_stop(admin->ctx);
+        admin->ctx = NULL;
+    }
+
+    hashMap_destroy(admin->exportedServices, false, false);
+    arrayList_destroy(admin->importedServices);
+
+    logHelper_stop(admin->loghelper);
+    logHelper_destroy(&admin->loghelper);
+
+    return status;
+}
+
+/**
+ * Request: http://host:port/services/{service}/{request}
+ */
+//void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) {
+
+celix_status_t importRegistration_getFactory(import_registration_pt import, service_factory_pt *factory);
+
+static int remoteServiceAdmin_callback(struct mg_connection *conn) {
+    int result = 1; // zero means: let civetweb handle it further, any non-zero value means it is handled by us...
+
+    const struct mg_request_info *request_info = mg_get_request_info(conn);
+    if (request_info->uri != NULL) {
+        remote_service_admin_pt rsa = request_info->user_data;
+
+
+        if (strncmp(request_info->uri, "/service/", 9) == 0 && strcmp("POST", request_info->request_method) == 0) {
+
+            // uri = /services/myservice/call
+            const char *uri = request_info->uri;
+            // rest = myservice/call
+
+            const char *rest = uri+9;
+            char *interfaceStart = strchr(rest, '/');
+            int pos = interfaceStart - rest;
+            char service[pos+1];
+            strncpy(service, rest, pos);
+            service[pos] = '\0';
+            unsigned long serviceId = strtoul(service,NULL,10);
+
+            celixThreadMutex_lock(&rsa->exportedServicesLock);
+
+            //find endpoint
+            export_registration_pt export = NULL;
+            hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
+            while (hashMapIterator_hasNext(iter)) {
+                hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+                array_list_pt exports = hashMapEntry_getValue(entry);
+                int expIt = 0;
+                for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
+                    export_registration_pt check = arrayList_get(exports, expIt);
+                    export_reference_pt  ref = NULL;
+                    exportRegistration_getExportReference(check, &ref);
+                    endpoint_description_pt  checkEndpoint = NULL;
+                    exportReference_getExportedEndpoint(ref, &checkEndpoint);
+                    if (serviceId == checkEndpoint->serviceId) {
+                        export = check;
+                        free(ref);
+                        break;
+                    }
+                    free(ref);
+                }
+            }
+            hashMapIterator_destroy(iter);
+
+            if (export != NULL) {
+
+                uint64_t datalength = request_info->content_length;
+                char* data = malloc(datalength + 1);
+                mg_read(conn, data, datalength);
+                data[datalength] = '\0';
+
+                char *response = NULL;
+                int responceLength = 0;
+                int rc = exportRegistration_call(export, data, -1, &response, &responceLength);
+                if (rc != CELIX_SUCCESS) {
+                    RSA_LOG_ERROR(rsa, "Error trying to invoke remove service, got error %i\n", rc);
+                }
+
+                if (rc == CELIX_SUCCESS && response != NULL) {
+                    mg_write(conn, data_response_headers, strlen(data_response_headers));
+                    mg_write(conn, response, strlen(response));
+                    free(response);
+                } else {
+                    mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
+                }
+                result = 1;
+
+                free(data);
+            } else {
+                result = 0;
+                RSA_LOG_WARNING(rsa, "NO export registration found for service id %lu", serviceId);
+            }
+
+            celixThreadMutex_unlock(&rsa->exportedServicesLock);
+
+        }
+    }
+
+    return result;
+}
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
+    celix_status_t status;
+
+    arrayList_create(registrations);
+    array_list_pt references = NULL;
+    service_reference_pt reference = NULL;
+    char filter [256];
+
+    snprintf(filter, 256, "(%s=%s)", (char *)OSGI_FRAMEWORK_SERVICE_ID, serviceId);
+
+    status = bundleContext_getServiceReferences(admin->context, NULL, filter, &references);
+
+    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId);
+
+    int i;
+    int size = arrayList_size(references);
+    for (i = 0; i < size; i += 1) {
+        if (i == 0) {
+            reference = arrayList_get(references, i);
+        } else {
+            bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i));
+        }
+    }
+    arrayList_destroy(references);
+
+    if (reference == NULL) {
+        logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
+        status = CELIX_ILLEGAL_STATE;
+    }
+
+    const char *exports = NULL;
+    const char *provided = NULL;
+    if (status == CELIX_SUCCESS) {
+        serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
+        serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
+
+        if (exports == NULL || provided == NULL || strcmp(exports, provided) != 0) {
+            logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
+            status = CELIX_ILLEGAL_STATE;
+        } else {
+            logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        const char *interface = provided;
+        endpoint_description_pt endpoint = NULL;
+        export_registration_pt registration = NULL;
+
+        remoteServiceAdmin_createEndpointDescription(admin, reference, properties, (char*)interface, &endpoint);
+        //TODO precheck if descriptor exists
+        status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, &registration);
+        if (status == CELIX_SUCCESS) {
+            status = exportRegistration_start(registration);
+            if (status == CELIX_SUCCESS) {
+                arrayList_add(*registrations, registration);
+            }
+        }
+    }
+
+
+    if (status == CELIX_SUCCESS) {
+        celixThreadMutex_lock(&admin->exportedServicesLock);
+        hashMap_put(admin->exportedServices, reference, *registrations);
+        celixThreadMutex_unlock(&admin->exportedServicesLock);
+    }
+    else{
+    	arrayList_destroy(*registrations);
+    	*registrations = NULL;
+    }
+
+    return status;
+}
+
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration) {
+    celix_status_t status;
+
+    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing exported service");
+
+    export_reference_pt  ref = NULL;
+    status = exportRegistration_getExportReference(registration, &ref);
+
+    if (status == CELIX_SUCCESS && ref != NULL) {
+    	service_reference_pt servRef;
+        celixThreadMutex_lock(&admin->exportedServicesLock);
+    	exportReference_getExportedService(ref, &servRef);
+
+    	array_list_pt exports = (array_list_pt)hashMap_remove(admin->exportedServices, servRef);
+    	if(exports!=NULL){
+    		arrayList_destroy(exports);
+    	}
+
+        exportRegistration_close(registration);
+        exportRegistration_destroy(registration);
+
+        celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+        free(ref);
+
+    } else {
+    	logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot find reference for registration");
+    }
+
+    return status;
+}
+
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, char *interface, endpoint_description_pt *endpoint) {
+
+    celix_status_t status = CELIX_SUCCESS;
+    properties_pt endpointProperties = properties_create();
+
+
+    unsigned int size = 0;
+    char **keys;
+
+    serviceReference_getPropertyKeys(reference, &keys, &size);
+    for (int i = 0; i < size; i++) {
+        char *key = keys[i];
+        const char *value = NULL;
+
+        if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS
+            && strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
+            && strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
+            properties_set(endpointProperties, key, value);
+        }
+    }
+
+    hash_map_entry_pt entry = hashMap_getEntry(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+
+    char* key = hashMapEntry_getKey(entry);
+    char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+    const char *uuid = NULL;
+
+    char buf[512];
+    snprintf(buf, 512,  "/service/%s/%s", serviceId, interface);
+
+    char url[1024];
+    snprintf(url, 1024, "http://%s:%s%s", admin->ip, admin->port, buf);
+
+    uuid_t endpoint_uid;
+    uuid_generate(endpoint_uid);
+    char endpoint_uuid[37];
+    uuid_unparse_lower(endpoint_uid, endpoint_uuid);
+
+    bundleContext_getProperty(admin->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+    properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+    properties_set(endpointProperties, (char*) OSGI_FRAMEWORK_OBJECTCLASS, interface);
+    properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId);
+    properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid);
+    properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true");
+    properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) CONFIGURATION_TYPE);
+    properties_set(endpointProperties, (char*) ENDPOINT_URL, url);
+
+    if (props != NULL) {
+        hash_map_iterator_pt propIter = hashMapIterator_create(props);
+        while (hashMapIterator_hasNext(propIter)) {
+    	    hash_map_entry_pt entry = hashMapIterator_nextEntry(propIter);
+    	    properties_set(endpointProperties, (char*)hashMapEntry_getKey(entry), (char*)hashMapEntry_getValue(entry));
+        }
+        hashMapIterator_destroy(propIter);
+    }
+
+    *endpoint = calloc(1, sizeof(**endpoint));
+    if (!*endpoint) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*endpoint)->id = (char*)properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
+        const char *serviceId = NULL;
+        serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+        (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
+        (*endpoint)->frameworkUUID = (char*) properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+        (*endpoint)->service = strndup(interface, 1024*10);
+        (*endpoint)->properties = endpointProperties;
+    }
+
+    free(key);
+    free(serviceId);
+    free(keys);
+
+    return status;
+}
+
+static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip) {
+    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+    struct ifaddrs *ifaddr, *ifa;
+    char host[NI_MAXHOST];
+
+    if (getifaddrs(&ifaddr) != -1)
+    {
+        for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+        {
+            if (ifa->ifa_addr == NULL)
+                continue;
+
+            if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+                if (interface == NULL) {
+                    *ip = strdup(host);
+                    status = CELIX_SUCCESS;
+                }
+                else if (strcmp(ifa->ifa_name, interface) == 0) {
+                    *ip = strdup(host);
+                    status = CELIX_SUCCESS;
+                }
+            }
+        }
+
+        freeifaddrs(ifaddr);
+    }
+
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description)
+{
+    celix_status_t status = CELIX_SUCCESS;
+
+    properties_destroy((*description)->properties);
+    free((*description)->service);
+    free(*description);
+
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+}
+
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+}
+
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *out) {
+    celix_status_t status = CELIX_SUCCESS;
+    import_registration_pt import = NULL;
+
+    const char *objectClass = properties_get(endpointDescription->properties, "objectClass");
+    const char *serviceVersion = properties_get(endpointDescription->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION);
+
+    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
+    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "Registering service factory (proxy) for service '%s'\n", objectClass);
+
+    if (objectClass != NULL) {
+        status = importRegistration_create(admin->context, endpointDescription, objectClass, serviceVersion, &import);
+    }
+    if (status == CELIX_SUCCESS && import != NULL) {
+        importRegistration_setSendFn(import, (send_func_type) remoteServiceAdmin_send, admin);
+    }
+
+    if (status == CELIX_SUCCESS && import != NULL) {
+        status = importRegistration_start(import);
+    }
+
+    celixThreadMutex_lock(&admin->importedServicesLock);
+    arrayList_add(admin->importedServices, import);
+    celixThreadMutex_unlock(&admin->importedServicesLock);
+
+    if (status == CELIX_SUCCESS) {
+        *out = import;
+    }
+
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing imported service");
+
+    celixThreadMutex_lock(&admin->importedServicesLock);
+    int i;
+    int size = arrayList_size(admin->importedServices);
+    import_registration_pt  current  = NULL;
+    for (i = 0; i < size; i += 1) {
+        current = arrayList_get(admin->importedServices, i);
+        if (current == registration) {
+            arrayList_remove(admin->importedServices, i);
+            importRegistration_close(current);
+            importRegistration_destroy(current);
+            break;
+        }
+    }
+    celixThreadMutex_unlock(&admin->importedServicesLock);
+
+    return status;
+}
+
+
+static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
+    remote_service_admin_pt  rsa = handle;
+    struct post post;
+    post.readptr = request;
+    post.size = strlen(request);
+
+    struct get get;
+    get.size = 0;
+    get.writeptr = malloc(1);
+
+    char *serviceUrl = (char*)properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
+    char url[256];
+    snprintf(url, 256, "%s", serviceUrl);
+
+    // assume the default timeout
+    int timeout = DEFAULT_TIMEOUT;
+
+    const char *timeoutStr = NULL;
+    // Check if the endpoint has a timeout, if so, use it.
+    timeoutStr = (char*) properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
+    if (timeoutStr == NULL) {
+        // If not, get the global variable and use that one.
+        bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
+    }
+
+    // Update timeout if a property is used to set it.
+    if (timeoutStr != NULL) {
+        timeout = atoi(timeoutStr);
+    }
+
+    celix_status_t status = CELIX_SUCCESS;
+    CURL *curl;
+    CURLcode res;
+
+    curl = curl_easy_init();
+    if(!curl) {
+        status = CELIX_ILLEGAL_STATE;
+    } else {
+        curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+        curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+        curl_easy_setopt(curl, CURLOPT_URL, url);
+        curl_easy_setopt(curl, CURLOPT_POST, 1L);
+        curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
+        curl_easy_setopt(curl, CURLOPT_READDATA, &post);
+        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
+        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
+        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
+        logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
+        res = curl_easy_perform(curl);
+
+        *reply = get.writeptr;
+        *replyStatus = res;
+
+        curl_easy_cleanup(curl);
+    }
+
+    return status;
+}
+
+static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp) {
+    struct post *post = userp;
+
+    if (post->size) {
+        *(char *) ptr = post->readptr[0];
+        post->readptr++;
+        post->size--;
+        return 1;
+    }
+
+    return 0;
+}
+
+static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {
+    size_t realsize = size * nmemb;
+    struct get *mem = (struct get *)userp;
+
+    mem->writeptr = realloc(mem->writeptr, mem->size + realsize + 1);
+    if (mem->writeptr == NULL) {
+        /* out of memory! */
+        printf("not enough memory (realloc returned NULL)");
+        exit(EXIT_FAILURE);
+    }
+
+    memcpy(&(mem->writeptr[mem->size]), contents, realsize);
+    mem->size += realsize;
+    mem->writeptr[mem->size] = 0;
+
+    return realsize;
+}
+
+
+static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...) {
+    va_list ap;
+    va_start(ap, msg);
+    int levels[5] = {0, OSGI_LOGSERVICE_ERROR, OSGI_LOGSERVICE_WARNING, OSGI_LOGSERVICE_INFO, OSGI_LOGSERVICE_DEBUG};
+
+    char buf1[256];
+    snprintf(buf1, 256, "FILE:%s, LINE:%i, MSG:", file, line);
+
+    char buf2[256];
+    vsnprintf(buf2, 256, msg, ap);
+    logHelper_log(admin->loghelper, levels[level], "%s%s", buf1, buf2);
+    va_end(ap);
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h
new file mode 100644
index 0000000..8b282f1
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h
@@ -0,0 +1,57 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_http_impl.h
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+
+
+#include "bundle_context.h"
+#include "endpoint_description.h"
+
+//typedef struct remote_service_admin *remote_service_admin_pt;
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration);
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
+
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
+celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service);
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
+celix_status_t importReference_getImportedService(import_reference_pt reference);
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
+
+#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
index 543d5a1..b3b272e 100644
--- a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
@@ -31,10 +31,8 @@ add_executable(test_rsa_dfi
     run_tests.cpp
     rsa_tests.cpp
     rsa_client_server_tests.cpp
-
-    ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
 )
-target_link_libraries(test_rsa_dfi Celix::framework ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY})
+target_link_libraries(test_rsa_dfi PRIVATE Celix::framework ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY} remote_service_admin_common)
 
 get_property(rsa_bundle_file TARGET remote_service_admin_dfi PROPERTY BUNDLE_FILE)
 get_property(calc_bundle_file TARGET calculator PROPERTY BUNDLE_FILE)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
index 27c3804..65b18e8 100644
--- a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
@@ -15,14 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories(
-        ${CPPUTEST_INCLUDE_DIR}
-        ${PROJECT_SOURCE_DIR}/framework/public/include
-        ${PROJECT_SOURCE_DIR}/utils/public/include
-        ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_service/public/include
-)
-
-
 add_bundle(rsa_dfi_tst_bundle
     VERSION 0.0.1
     SOURCES
@@ -30,8 +22,8 @@ add_bundle(rsa_dfi_tst_bundle
 )
 
 bundle_files(rsa_dfi_tst_bundle
-    ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
+    ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
     DESTINATION .
 )
-
-target_link_libraries(rsa_dfi_tst_bundle PRIVATE ${CPPUTEST_LIBRARY} )
+target_include_directories(rsa_dfi_tst_bundle PRIVATE calculator)
+target_link_libraries(rsa_dfi_tst_bundle PRIVATE ${CPPUTEST_LIBRARY} calculator_api)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/CMakeLists.txt b/remote_services/topology_manager/CMakeLists.txt
index 4bac4fd..defee5c 100644
--- a/remote_services/topology_manager/CMakeLists.txt
+++ b/remote_services/topology_manager/CMakeLists.txt
@@ -16,27 +16,19 @@
 # under the License.
 celix_subproject(RSA_TOPOLOGY_MANAGER "Option to enable building the Remote Service Admin Service SHM bundle" ON DEPS REMOTE_SERVICE_ADMIN_DFI)
 if (RSA_TOPOLOGY_MANAGER)
-    include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/topology_manager/private/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
-    include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/topology_manager/public/include")
 
-    add_bundle(topology_manager SOURCES
-        private/src/topology_manager
-        private/src/scope
-        private/src/activator
-
-        private/include/topology_manager.h
-        public/include/tm_scope.h
+    add_bundle(topology_manager
+        SOURCES
+            src/topology_manager
+            src/scope
+            src/activator
         VERSION 0.9.0
         SYMBOLIC_NAME "apache_celix_rs_topology_manager"
-        NAME
-            "Apache Celix RS Topology Manager"
+        NAME "Apache Celix RS Topology Manager"
     )
-    target_link_libraries(topology_manager PRIVATE Celix::log_helper)
+    target_include_directories(topology_manager PRIVATE src)
+    target_include_directories(topology_manager PUBLIC include)
+    target_link_libraries(topology_manager PRIVATE Celix::log_helper remote_service_admin_api)
 
     install_bundle(topology_manager)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/include/tm_scope.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/include/tm_scope.h b/remote_services/topology_manager/include/tm_scope.h
new file mode 100644
index 0000000..d4f60ca
--- /dev/null
+++ b/remote_services/topology_manager/include/tm_scope.h
@@ -0,0 +1,46 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * tm_scope.h
+ *
+ *  \date       Oct 29, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef TM_SCOPE_H_
+#define TM_SCOPE_H_
+
+#include "celix_errno.h"
+
+#define TOPOLOGYMANAGER_SCOPE_SERVICE "tm_scope"
+
+
+struct tm_scope_service {
+    void *handle;	// scope_pt
+    celix_status_t (*addExportScope)(void *handle, char *filter, properties_pt props);
+    celix_status_t (*removeExportScope)(void *handle, char *filter);
+    celix_status_t (*addImportScope)(void *handle, char *filter);
+    celix_status_t (*removeImportScope)(void *handle, char *filter);
+};
+
+typedef struct tm_scope_service tm_scope_service_t;
+typedef tm_scope_service_t *tm_scope_service_pt;
+
+#endif /* TM_SCOPE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/include/scope.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/include/scope.h b/remote_services/topology_manager/private/include/scope.h
deleted file mode 100644
index 4035e2c..0000000
--- a/remote_services/topology_manager/private/include/scope.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * scope.h
- *
- *  \date       Sep 29, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef TOPOLOGY_SCOPE_H_
-#define TOPOLOGY_SCOPE_H_
-
-#include "celixbool.h"
-#include "celix_errno.h"
-#include "celix_threads.h"
-#include "hash_map.h"
-#include "endpoint_description.h"
-#include "properties.h"
-#include "service_reference.h"
-#include "tm_scope.h"
-
-typedef struct scope *scope_pt;
-
-
-
-/* \brief  create scope structure
- *
- * \param  owning component pointer
- * \param  scope to be created
- *
- * \return CELIX_SUCCESS
- *         CELIX_ENOMEM
- */
-celix_status_t scope_scopeCreate(void *handle, scope_pt *scope);
-
-/* \brief  destroy scope structure
- *
- * \param  scope to be destroyed
- *
- * \return CELIX_SUCCESS
- */
-celix_status_t scope_scopeDestroy(scope_pt scope);
-
-/* \brief  register export scope change callback of topology manager
- *
- * \param  scope structure
- * \param  changed function pointer
- *
- * \return -
- */
-void scope_setExportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName));
-
-/* \brief  register import scope change callback of topology manager
- *
- * \param  scope structure
- * \param  changed function pointer
- *
- * \return -
- */
-void scope_setImportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName));
-
-
-/* \brief  Test if scope allows import of service
- *
- * \param  scope containing import rules
- * \param  endpoint import service endpoint description
- *
- * \return true import allowed
- *         false import not allowed
- */
-bool scope_allowImport(scope_pt scope, endpoint_description_pt endpoint);
-
-/* \brief  Test if scope allows import of service
- *
- * \param  scope containing export rules
- * \param  reference to service
- * \param  props, additional properties defining restrictions for the exported service
- *                NULL if no additional restrictions found
- *
- * \return CELIX_SUCCESS
- *
- */
-celix_status_t scope_getExportProperties(scope_pt scope, service_reference_pt reference, properties_pt *props);
-
-/* \brief  add restricted scope for specified exported service
- *
- * \param  handle pointer to scope
- * \param  filter, filter string
- * \param  props additional properties defining restrictions for the exported service
- *
- * \return CELIX_SUCCESS if added to scope
- *         CELIX_ILLEGAL_ARGUMENT if service scope is already restricted before
- *
- */
-celix_status_t tm_addExportScope(void *handle, char *filter, properties_pt props);
-
-/* \brief  remove restricted scope for specified exported service
- *
- * \param  handle pointer to scope
- * \param  filter, filter string
- *
- * \return CELIX_SUCCESS if removed
- *         CELIX_ILLEGAL_ARGUMENT if service not found in scope
- *
- */
-celix_status_t tm_removeExportScope(void *handle, char *filter);
-
-/* \brief  add restricted scope for specified imported service
- *
- * \param  handle pointer to scope
- * \param  filter, filter string
- * \param  props additional properties defining restrictions for the imported service
- *
- * \return CELIX_SUCCESS if added to scope
- *         CELIX_ILLEGAL_ARGUMENT if service scope is already restricted before
- *
- */
-celix_status_t tm_addImportScope(void *handle, char *filter);
-
-
-/* \brief  remove restricted scope for specified imported service
- *
- * \param  handle pointer to scope
- * \param  filter, filter string
- *
- * \return CELIX_SUCCESS if removed
- *         CELIX_ILLEGAL_ARGUMENT if service not found in scope
- *
- */
-celix_status_t tm_removeImportScope(void *handle, char *filter);
-
-
-#endif // TOPOLOGY_SCOPE_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/include/topology_manager.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/include/topology_manager.h b/remote_services/topology_manager/private/include/topology_manager.h
deleted file mode 100644
index 7e5e917..0000000
--- a/remote_services/topology_manager/private/include/topology_manager.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * topology_manager.h
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef TOPOLOGY_MANAGER_H_
-#define TOPOLOGY_MANAGER_H_
-
-#include "endpoint_listener.h"
-#include "service_reference.h"
-#include "bundle_context.h"
-#include "log_helper.h"
-#include "scope.h"
-
-#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
-
-typedef struct topology_manager *topology_manager_pt;
-
-celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager, void **scope);
-celix_status_t topologyManager_destroy(topology_manager_pt manager);
-celix_status_t topologyManager_closeImports(topology_manager_pt manager);
-
-celix_status_t topologyManager_rsaAdding(void *handle, service_reference_pt reference, void **service);
-celix_status_t topologyManager_rsaAdded(void *handle, service_reference_pt reference, void *service);
-celix_status_t topologyManager_rsaModified(void *handle, service_reference_pt reference, void *service);
-celix_status_t topologyManager_rsaRemoved(void *handle, service_reference_pt reference, void *service);
-
-celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service);
-celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service);
-celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void* service);
-celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void* service);
-
-celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event);
-
-celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter);
-celix_status_t topologyManager_removeImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter);
-
-celix_status_t topologyManager_addExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId);
-celix_status_t topologyManager_removeExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId);
-
-celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt listeners);
-celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt listeners);
-
-#endif /* TOPOLOGY_MANAGER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/src/activator.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/src/activator.c b/remote_services/topology_manager/private/src/activator.c
deleted file mode 100644
index 7f39a25..0000000
--- a/remote_services/topology_manager/private/src/activator.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * activator.c
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "constants.h"
-#include "bundle_activator.h"
-#include "service_tracker.h"
-#include "service_registration.h"
-
-#include "topology_manager.h"
-#include "endpoint_listener.h"
-#include "remote_constants.h"
-#include "listener_hook_service.h"
-#include "log_service.h"
-#include "log_helper.h"
-#include "scope.h"
-#include "tm_scope.h"
-#include "topology_manager.h"
-
-struct activator {
-	bundle_context_pt context;
-
-	topology_manager_pt manager;
-
-	service_tracker_pt endpointListenerTracker;
-	service_tracker_pt remoteServiceAdminTracker;
-	service_listener_pt serviceListener;
-
-	endpoint_listener_pt endpointListener;
-	service_registration_pt endpointListenerService;
-
-	listener_hook_service_pt hookService;
-	service_registration_pt hook;
-
-	tm_scope_service_pt	scopeService;
-	service_registration_pt scopeReg;
-
-	log_helper_pt loghelper;
-};
-
-
-static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker);
-static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker);
-static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener);
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = NULL;
-	void *scope;
-
-	activator = calloc(1, sizeof(struct activator));
-
-	if (!activator) {
-		return CELIX_ENOMEM;
-	}
-
-	activator->context = context;
-	activator->endpointListenerService = NULL;
-	activator->endpointListenerTracker = NULL;
-	activator->hook = NULL;
-	activator->manager = NULL;
-	activator->remoteServiceAdminTracker = NULL;
-	activator->serviceListener = NULL;
-	activator->scopeService = calloc(1, sizeof(*(activator->scopeService)));
-	if (activator->scopeService == NULL)
-	{
-		free(activator);
-		return CELIX_ENOMEM;
-	}
-
-	activator->scopeService->addExportScope = tm_addExportScope;
-	activator->scopeService->removeExportScope = tm_removeExportScope;
-	activator->scopeService->addImportScope = tm_addImportScope;
-	activator->scopeService->removeImportScope = tm_removeImportScope;
-	activator->scopeReg = NULL; // explicitly needed, otherwise exception
-
-	logHelper_create(context, &activator->loghelper);
-	logHelper_start(activator->loghelper);
-
-	status = topologyManager_create(context, activator->loghelper, &activator->manager, &scope);
-	activator->scopeService->handle = scope;
-
-	if (status == CELIX_SUCCESS) {
-		status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
-		if (status == CELIX_SUCCESS) {
-			status = bundleActivator_createRSATracker(activator, &activator->remoteServiceAdminTracker);
-			if (status == CELIX_SUCCESS) {
-				status = bundleActivator_createServiceListener(activator, &activator->serviceListener);
-				if (status == CELIX_SUCCESS) {
-					*userData = activator;
-				}
-			}
-		}
-	}
-
-	if(status != CELIX_SUCCESS){
-		bundleActivator_destroy(activator,context);
-	}
-
-	return status;
-}
-
-static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) {
-	celix_status_t status;
-
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(activator->manager, topologyManager_endpointListenerAdding, topologyManager_endpointListenerAdded, topologyManager_endpointListenerModified,
-			topologyManager_endpointListenerRemoved, &customizer);
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker);
-	}
-
-	return status;
-}
-
-static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker) {
-	celix_status_t status;
-
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(activator->manager, topologyManager_rsaAdding, topologyManager_rsaAdded, topologyManager_rsaModified, topologyManager_rsaRemoved, &customizer);
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_create(activator->context, OSGI_RSA_REMOTE_SERVICE_ADMIN, customizer, tracker);
-	}
-
-	return status;
-}
-
-static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*listener = malloc(sizeof(**listener));
-	if (!*listener) {
-		return CELIX_ENOMEM;
-	}
-
-	(*listener)->handle = activator->manager;
-	(*listener)->serviceChanged = topologyManager_serviceChanged;
-
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	celix_status_t status;
-	struct activator *activator = userData;
-
-	endpoint_listener_pt endpointListener = malloc(sizeof(*endpointListener));
-	endpointListener->handle = activator->manager;
-	endpointListener->endpointAdded = topologyManager_addImportedService;
-	endpointListener->endpointRemoved = topologyManager_removeImportedService;
-	activator->endpointListener = endpointListener;
-
-	const char *uuid = NULL;
-	status = bundleContext_getProperty(activator->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-	if (!uuid) {
-		logHelper_log(activator->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!");
-		return CELIX_ILLEGAL_STATE;
-	}
-
-	size_t len = 14 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
-	char *scope = malloc(len);
-	if (!scope) {
-		return CELIX_ENOMEM;
-	}
-
-	snprintf(scope, len, "(&(%s=*)(!(%s=%s)))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
-
-	logHelper_log(activator->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: endpoint listener scope is %s", scope);
-
-	properties_pt props = properties_create();
-	properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
-
-	// We can release the scope, as properties_set makes a copy of the key & value...
-	free(scope);
-
-	bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService);
-
-	listener_hook_service_pt hookService = malloc(sizeof(*hookService));
-	hookService->handle = activator->manager;
-	hookService->added = topologyManager_listenerAdded;
-	hookService->removed = topologyManager_listenerRemoved;
-	activator->hookService = hookService;
-
-	bundleContext_registerService(context, (char *) OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, hookService, NULL, &activator->hook);
-	bundleContext_addServiceListener(context, activator->serviceListener, "(service.exported.interfaces=*)");
-
-	if (status == CELIX_SUCCESS) {
-		serviceTracker_open(activator->remoteServiceAdminTracker);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_open(activator->endpointListenerTracker);
-	}
-
-	bundleContext_registerService(context, (char *) TOPOLOGYMANAGER_SCOPE_SERVICE, activator->scopeService, NULL, &activator->scopeReg);
-
-	array_list_pt references = NULL;
-	bundleContext_getServiceReferences(context, NULL, "(service.exported.interfaces=*)", &references);
-	int i;
-	for (i = 0; i < arrayList_size(references); i++) {
-		service_reference_pt reference = arrayList_get(references, i);
-		const char* serviceId = NULL;
-		status = CELIX_DO_IF(status, serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId));
-
-		CELIX_DO_IF(status, topologyManager_addExportedService(activator->manager, reference, (char*)serviceId));
-	}
-	arrayList_destroy(references);
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	if (serviceTracker_close(activator->remoteServiceAdminTracker) == CELIX_SUCCESS) {
-		serviceTracker_destroy(activator->remoteServiceAdminTracker);
-	}
-
-	if (serviceTracker_close(activator->endpointListenerTracker) == CELIX_SUCCESS) {
-		serviceTracker_destroy(activator->endpointListenerTracker);
-	}
-
-	bundleContext_removeServiceListener(context, activator->serviceListener);
-	free(activator->serviceListener);
-
-	serviceRegistration_unregister(activator->hook);
-	free(activator->hookService);
-
-	serviceRegistration_unregister(activator->endpointListenerService);
-	free(activator->endpointListener);
-
-	serviceRegistration_unregister(activator->scopeReg);
-
-	topologyManager_closeImports(activator->manager);
-
-	return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	struct activator *activator = userData;
-	if (!activator || !activator->manager) {
-		status = CELIX_BUNDLE_EXCEPTION;
-	} else {
-		logHelper_stop(activator->loghelper);
-		logHelper_destroy(&activator->loghelper);
-
-		status = topologyManager_destroy(activator->manager);
-
-		if (activator->scopeService) {
-			free(activator->scopeService);
-		}
-
-		free(activator);
-	}
-
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/src/scope.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/src/scope.c b/remote_services/topology_manager/private/src/scope.c
deleted file mode 100644
index b81d050..0000000
--- a/remote_services/topology_manager/private/src/scope.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * scope.c
- *
- *  \date       Sep 29, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "scope.h"
-#include "tm_scope.h"
-#include "topology_manager.h"
-#include "utils.h"
-
-struct scope_item {
-    properties_pt props;
-};
-
-struct scope {
-    void *manager;	// owner of the scope datastructure
-    celix_thread_mutex_t exportScopeLock;
-    hash_map_pt exportScopes;           // key is filter, value is scope_item (properties set)
-
-    celix_thread_mutex_t importScopeLock;
-    array_list_pt importScopes;			// list of filters
-
-    celix_status_t (*exportScopeChangedHandler)(void* manager, char *filter);
-    celix_status_t (*importScopeChangedHandler)(void* manager, char *filter);
-};
-
-static celix_status_t import_equal(const void *, const void *, bool *equals);
-
-/*
- * SERVICES
- */
-
-celix_status_t tm_addExportScope(void *handle, char *filter, properties_pt props) {
-    celix_status_t status = CELIX_SUCCESS;
-    scope_pt scope = (scope_pt) handle;
-    properties_pt present;
-
-    if (handle == NULL)
-        return CELIX_ILLEGAL_ARGUMENT;
-
-    if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
-        // For now we just don't allow two exactly the same filters
-        // TODO: What we actually need is the following
-        // If part of the new filter is already present in any of the filters in exportScopes
-        // we have to assure that the new filter defines other property keys than the property keys
-        // in the already defined filter!
-        present = (properties_pt) hashMap_get(scope->exportScopes, filter);
-        if (present == NULL) {
-            struct scope_item *item = calloc(1, sizeof(*item));
-            if (item == NULL) {
-                status = CELIX_ENOMEM;
-            } else {
-                item->props = props;
-                hashMap_put(scope->exportScopes, (void*) strdup(filter), (void*) item);
-            }
-        } else {
-            // don't allow the same filter twice
-            properties_destroy(props);
-            status = CELIX_ILLEGAL_ARGUMENT;
-        }
-        celixThreadMutex_unlock(&scope->exportScopeLock);
-    }
-
-    if (scope->exportScopeChangedHandler != NULL) {
-        status = CELIX_DO_IF(status, scope->exportScopeChangedHandler(scope->manager, filter));
-    }
-
-    return status;
-}
-
-celix_status_t tm_removeExportScope(void *handle, char *filter) {
-    celix_status_t status = CELIX_SUCCESS;
-    scope_pt scope = (scope_pt) handle;
-
-    if (handle == NULL)
-        return CELIX_ILLEGAL_ARGUMENT;
-
-    if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
-        struct scope_item *present = (struct scope_item *) hashMap_get(scope->exportScopes, filter);
-        if (present == NULL) {
-            status = CELIX_ILLEGAL_ARGUMENT;
-        } else {
-            properties_destroy(present->props);
-            hashMap_remove(scope->exportScopes, filter); // frees also the item!
-        }
-        celixThreadMutex_unlock(&scope->exportScopeLock);
-    }
-    if (scope->exportScopeChangedHandler != NULL) {
-        status = CELIX_DO_IF(status, scope->exportScopeChangedHandler(scope->manager, filter));
-    }
-    return status;
-}
-
-celix_status_t tm_addImportScope(void *handle, char *filter) {
-    celix_status_t status = CELIX_SUCCESS;
-    scope_pt scope = (scope_pt) handle;
-
-    filter_pt new;
-
-    if (handle == NULL)
-        return CELIX_ILLEGAL_ARGUMENT;
-    new = filter_create(filter);
-    if (new == NULL) {
-        return CELIX_ILLEGAL_ARGUMENT; // filter not parseble
-    }
-    if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
-        int index = arrayList_indexOf(scope->importScopes, new);
-        filter_pt present = (filter_pt) arrayList_get(scope->importScopes, index);
-        if (present == NULL) {
-            arrayList_add(scope->importScopes, new);
-        } else {
-            filter_destroy(new);
-            status = CELIX_ILLEGAL_ARGUMENT;
-        }
-
-        celixThreadMutex_unlock(&scope->importScopeLock);
-    }
-    if (scope->importScopeChangedHandler != NULL) {
-        status = CELIX_DO_IF(status, scope->importScopeChangedHandler(scope->manager, filter));
-    }
-    return status;
-}
-
-celix_status_t tm_removeImportScope(void *handle, char *filter) {
-    celix_status_t status = CELIX_SUCCESS;
-    scope_pt scope = (scope_pt) handle;
-    filter_pt new;
-
-    if (handle == NULL)
-        return CELIX_ILLEGAL_ARGUMENT;
-
-    new = filter_create(filter);
-    if (new == NULL) {
-        return CELIX_ILLEGAL_ARGUMENT; // filter not parseble
-    }
-
-    if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
-        int index = arrayList_indexOf(scope->importScopes, new);
-        filter_pt present = (filter_pt) arrayList_get(scope->importScopes, index);
-        if (present == NULL)
-            status = CELIX_ILLEGAL_ARGUMENT;
-        else {
-            arrayList_removeElement(scope->importScopes, present);
-            filter_destroy(present);
-        }
-        celixThreadMutex_unlock(&scope->importScopeLock);
-    }
-    if (scope->importScopeChangedHandler != NULL) {
-        status = CELIX_DO_IF(status, scope->importScopeChangedHandler(scope->manager, filter));
-    }
-    filter_destroy(new);
-    return status;
-}
-
-/*****************************************************************************
- * GLOBAL FUNCTIONS
- *****************************************************************************/
-
-void scope_setExportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName)) {
-    scope->exportScopeChangedHandler = changed;
-}
-
-void scope_setImportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName)) {
-    scope->importScopeChangedHandler = changed;
-}
-
-celix_status_t scope_scopeCreate(void *handle, scope_pt *scope) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    *scope = calloc(1, sizeof **scope);
-
-    if (*scope == NULL) {
-        return CELIX_ENOMEM;
-    }
-
-    (*scope)->manager = handle;
-    celixThreadMutex_create(&(*scope)->exportScopeLock, NULL);
-    celixThreadMutex_create(&(*scope)->importScopeLock, NULL);
-
-    (*scope)->exportScopes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-    arrayList_createWithEquals(import_equal, &((*scope)->importScopes));
-    (*scope)->exportScopeChangedHandler = NULL;
-
-    return status;
-}
-
-celix_status_t scope_scopeDestroy(scope_pt scope) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
-        hash_map_iterator_pt iter = hashMapIterator_create(scope->exportScopes);
-        while (hashMapIterator_hasNext(iter)) {
-            hash_map_entry_pt scopedEntry = hashMapIterator_nextEntry(iter);
-            struct scope_item *item = (struct scope_item*) hashMapEntry_getValue(scopedEntry);
-            properties_destroy(item->props);
-        }
-        hashMapIterator_destroy(iter);
-        hashMap_destroy(scope->exportScopes, true, true); // free keys, free values
-        celixThreadMutex_unlock(&scope->exportScopeLock);
-    }
-
-    if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
-        array_list_iterator_pt imp_iter = arrayListIterator_create(scope->importScopes);
-        while (arrayListIterator_hasNext(imp_iter)) {
-            filter_pt element = (filter_pt) arrayListIterator_next(imp_iter);
-            filter_destroy(element);
-            // no need to call arrayList_removeElement(element) because complete list is destroyed
-        }
-        arrayListIterator_destroy(imp_iter);
-        arrayList_destroy(scope->importScopes);
-        celixThreadMutex_unlock(&scope->importScopeLock);
-    }
-
-    celixThreadMutex_destroy(&scope->exportScopeLock);
-    celixThreadMutex_destroy(&scope->importScopeLock);
-    free(scope);
-    return status;
-}
-
-/*****************************************************************************
- * STATIC FUNCTIONS
- *****************************************************************************/
-static celix_status_t import_equal(const void *src, const void *dest, bool *equals) {
-    celix_status_t status;
-
-    filter_pt src_filter = (filter_pt) src;
-    filter_pt dest_filter = (filter_pt) dest;
-    status = filter_match_filter(src_filter, dest_filter, equals);
-    return status;
-}
-
-bool scope_allowImport(scope_pt scope, endpoint_description_pt endpoint) {
-    bool allowImport = false;
-    array_list_iterator_pt iter;
-
-    if (celixThreadMutex_lock(&(scope->importScopeLock)) == CELIX_SUCCESS) {
-        if (arrayList_size(scope->importScopes) == 0) {
-            allowImport = true;
-        } else {
-            iter = arrayListIterator_create(scope->importScopes);
-            while ((allowImport == false) && arrayListIterator_hasNext(iter)) {
-                filter_pt element = (filter_pt) arrayListIterator_next(iter);
-                filter_match(element, endpoint->properties, &allowImport);
-            }
-            arrayListIterator_destroy(iter);
-        }
-        celixThreadMutex_unlock(&scope->importScopeLock);
-    }
-    return allowImport;
-}
-
-celix_status_t scope_getExportProperties(scope_pt scope, service_reference_pt reference, properties_pt *props) {
-    celix_status_t status = CELIX_SUCCESS;
-    unsigned int size = 0;
-    char **keys;
-    bool found = false;
-
-    *props = NULL;
-    properties_pt serviceProperties = properties_create();  // GB: not sure if a copy is needed
-                                                            // or serviceReference_getProperties() is
-                                                            // is acceptable
-
-    serviceReference_getPropertyKeys(reference, &keys, &size);
-    for (int i = 0; i < size; i++) {
-        char *key = keys[i];
-        const char* value = NULL;
-
-        if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS) {
-//        		&& strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
-//        		&& strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
-            properties_set(serviceProperties, key, value);
-        }
-
-    }
-
-    free(keys);
-
-    if (celixThreadMutex_lock(&(scope->exportScopeLock)) == CELIX_SUCCESS) {
-        hash_map_iterator_pt scopedPropIter = hashMapIterator_create(scope->exportScopes);
-        // TODO: now stopping if first filter matches, alternatively we could build up
-        //       the additional output properties for each filter that matches?
-        while ((!found) && hashMapIterator_hasNext(scopedPropIter)) {
-            hash_map_entry_pt scopedEntry = hashMapIterator_nextEntry(scopedPropIter);
-            char *filterStr = (char *) hashMapEntry_getKey(scopedEntry);
-            filter_pt filter = filter_create(filterStr);
-            if (filter != NULL) {
-                // test if the scope filter matches the exported service properties
-                status = filter_match(filter, serviceProperties, &found);
-                if (found) {
-                    struct scope_item *item = (struct scope_item *) hashMapEntry_getValue(scopedEntry);
-                    *props = item->props;
-                }
-            }
-            filter_destroy(filter);
-        }
-        hashMapIterator_destroy(scopedPropIter);
-        properties_destroy(serviceProperties);
-
-        celixThreadMutex_unlock(&(scope->exportScopeLock));
-    }
-
-    return status;
-}


[09/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/private/include/calculator_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/private/include/calculator_impl.h b/remote_services/examples/calculator_service/private/include/calculator_impl.h
deleted file mode 100644
index 5e075e4..0000000
--- a/remote_services/examples/calculator_service/private/include/calculator_impl.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * calculator_impl.h
- *
- *  \date       Oct 5, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef CALCULATOR_IMPL_H_
-#define CALCULATOR_IMPL_H_
-
-#include "celix_errno.h"
-
-#include "calculator_service.h"
-
-struct calculator {
-};
-
-celix_status_t calculator_create(calculator_pt *calcuator);
-celix_status_t calculator_destroy(calculator_pt *calcuator);
-celix_status_t calculator_add(calculator_pt calcuator, double a, double b, double *result);
-celix_status_t calculator_sub(calculator_pt calcuator, double a, double b, double *result);
-celix_status_t calculator_sqrt(calculator_pt calcuator, double a, double *result);
-
-#endif /* CALCULATOR_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/private/src/calculator_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/private/src/calculator_activator.c b/remote_services/examples/calculator_service/private/src/calculator_activator.c
deleted file mode 100644
index 688a7b0..0000000
--- a/remote_services/examples/calculator_service/private/src/calculator_activator.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * calculator_activator.c
- *
- *  \date       Oct 5, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdlib.h>
-
-#include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
-
-#include "calculator_impl.h"
-#include "remote_constants.h"
-
-struct activator {
-	calculator_pt calculator;
-	calculator_service_pt service;
-
-	service_registration_pt calculatorReg;
-	service_registration_pt calculatorReg2;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator;
-
-	activator = calloc(1, sizeof(*activator));
-	if (!activator) {
-		status = CELIX_ENOMEM;
-	} else {
-		activator->calculatorReg = NULL;
-		activator->calculatorReg2 = NULL;
-
-		*userData = activator;
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	properties_pt properties = NULL;
-
-	status = calculator_create(&activator->calculator);
-	if (status == CELIX_SUCCESS) {
-		activator->service = calloc(1, sizeof(*activator->service));
-		if (!activator->service) {
-			status = CELIX_ENOMEM;
-		} else {
-			activator->service->calculator = activator->calculator;
-			activator->service->add = calculator_add;
-			activator->service->sub = calculator_sub;
-			activator->service->sqrt = calculator_sqrt;
-
-			properties = properties_create();
-			properties_set(properties, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR_SERVICE);
-
-			bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg);
-
-			properties_pt properties2 = properties_create();
-			properties_set(properties2, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR2_SERVICE);
-			bundleContext_registerService(context, CALCULATOR2_SERVICE, activator->service, properties2, &activator->calculatorReg2);
-		}
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	serviceRegistration_unregister(activator->calculatorReg);
-	serviceRegistration_unregister(activator->calculatorReg2);
-
-	free(activator->service);
-
-	calculator_destroy(&activator->calculator);
-
-	return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	free(userData);
-
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/private/src/calculator_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/private/src/calculator_impl.c b/remote_services/examples/calculator_service/private/src/calculator_impl.c
deleted file mode 100644
index adccb52..0000000
--- a/remote_services/examples/calculator_service/private/src/calculator_impl.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * calculator_impl.c
- *
- *  \date       Oct 5, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <math.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "calculator_impl.h"
-
-celix_status_t calculator_create(calculator_pt *calculator) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*calculator = calloc(1, sizeof(**calculator));
-	if (!*calculator) {
-		status = CELIX_ENOMEM;
-	}
-
-	return status;
-}
-
-celix_status_t calculator_destroy(calculator_pt *calculator) {
-	free(*calculator);
-	return CELIX_SUCCESS;
-}
-
-celix_status_t calculator_add(calculator_pt calculator, double a, double b, double *result) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*result = a + b;
-	printf("CALCULATOR: Add: %f + %f = %f\n", a, b, *result);
-
-	return status;
-}
-
-celix_status_t calculator_sub(calculator_pt calculator, double a, double b, double *result) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*result = a - b;
-	printf("CALCULATOR: Sub: %f + %f = %f\n", a, b, *result);
-
-	return status;
-}
-
-celix_status_t calculator_sqrt(calculator_pt calculator, double a, double *result) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (a > 0) {
-		*result = sqrt(a);
-		printf("CALCULATOR: Sqrt: %f = %f\n", a, *result);
-	} else {
-		printf("CALCULATOR: Sqrt: %f = ERR\n", a);
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/public/include/calculator_service.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/public/include/calculator_service.h b/remote_services/examples/calculator_service/public/include/calculator_service.h
deleted file mode 100644
index 8e2f0dc..0000000
--- a/remote_services/examples/calculator_service/public/include/calculator_service.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * calculator_service.h
- *
- *  \date       Oct 5, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef CALCULATOR_SERVICE_H_
-#define CALCULATOR_SERVICE_H_
-
-#define CALCULATOR_SERVICE "org.apache.celix.calc.api.Calculator"
-#define CALCULATOR2_SERVICE "org.apache.celix.calc.api.Calculator2"
-
-
-typedef struct calculator *calculator_pt;
-
-typedef struct calculator_service *calculator_service_pt;
-
-/*
- * The calculator service definition corresponds to the following Java interface:
- *
- * interface Calculator {
- * 	 double add(double a, double b);
- * 	 double sub(double a, double b);
- * 	 double sqrt(double a);
- * }
- */
-struct calculator_service {
-	calculator_pt calculator;
-	int (*add)(calculator_pt calculator, double a, double b, double *result);
-	int (*sub)(calculator_pt calculator, double a, double b, double *result);
-  int (*sqrt)(calculator_pt calculator, double a, double *result);
-};
-
-
-
-#endif /* CALCULATOR_SERVICE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
deleted file mode 100644
index b784838..0000000
--- a/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
+++ /dev/null
@@ -1,11 +0,0 @@
-:header
-type=interface
-name=calculator
-version=1.3.0
-:annotations
-classname=org.example.Calculator
-:types
-:methods
-add(DD)D=add(#am=handle;PDD#am=pre;*D)N
-sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
-sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/src/calculator_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/src/calculator_activator.c b/remote_services/examples/calculator_service/src/calculator_activator.c
new file mode 100644
index 0000000..688a7b0
--- /dev/null
+++ b/remote_services/examples/calculator_service/src/calculator_activator.c
@@ -0,0 +1,110 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * calculator_activator.c
+ *
+ *  \date       Oct 5, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+
+#include "calculator_impl.h"
+#include "remote_constants.h"
+
+struct activator {
+	calculator_pt calculator;
+	calculator_service_pt service;
+
+	service_registration_pt calculatorReg;
+	service_registration_pt calculatorReg2;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator;
+
+	activator = calloc(1, sizeof(*activator));
+	if (!activator) {
+		status = CELIX_ENOMEM;
+	} else {
+		activator->calculatorReg = NULL;
+		activator->calculatorReg2 = NULL;
+
+		*userData = activator;
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	properties_pt properties = NULL;
+
+	status = calculator_create(&activator->calculator);
+	if (status == CELIX_SUCCESS) {
+		activator->service = calloc(1, sizeof(*activator->service));
+		if (!activator->service) {
+			status = CELIX_ENOMEM;
+		} else {
+			activator->service->calculator = activator->calculator;
+			activator->service->add = calculator_add;
+			activator->service->sub = calculator_sub;
+			activator->service->sqrt = calculator_sqrt;
+
+			properties = properties_create();
+			properties_set(properties, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR_SERVICE);
+
+			bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg);
+
+			properties_pt properties2 = properties_create();
+			properties_set(properties2, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR2_SERVICE);
+			bundleContext_registerService(context, CALCULATOR2_SERVICE, activator->service, properties2, &activator->calculatorReg2);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	serviceRegistration_unregister(activator->calculatorReg);
+	serviceRegistration_unregister(activator->calculatorReg2);
+
+	free(activator->service);
+
+	calculator_destroy(&activator->calculator);
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	free(userData);
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/src/calculator_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/src/calculator_impl.c b/remote_services/examples/calculator_service/src/calculator_impl.c
new file mode 100644
index 0000000..adccb52
--- /dev/null
+++ b/remote_services/examples/calculator_service/src/calculator_impl.c
@@ -0,0 +1,79 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * calculator_impl.c
+ *
+ *  \date       Oct 5, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <math.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "calculator_impl.h"
+
+celix_status_t calculator_create(calculator_pt *calculator) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*calculator = calloc(1, sizeof(**calculator));
+	if (!*calculator) {
+		status = CELIX_ENOMEM;
+	}
+
+	return status;
+}
+
+celix_status_t calculator_destroy(calculator_pt *calculator) {
+	free(*calculator);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t calculator_add(calculator_pt calculator, double a, double b, double *result) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*result = a + b;
+	printf("CALCULATOR: Add: %f + %f = %f\n", a, b, *result);
+
+	return status;
+}
+
+celix_status_t calculator_sub(calculator_pt calculator, double a, double b, double *result) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*result = a - b;
+	printf("CALCULATOR: Sub: %f + %f = %f\n", a, b, *result);
+
+	return status;
+}
+
+celix_status_t calculator_sqrt(calculator_pt calculator, double a, double *result) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (a > 0) {
+		*result = sqrt(a);
+		printf("CALCULATOR: Sqrt: %f = %f\n", a, *result);
+	} else {
+		printf("CALCULATOR: Sqrt: %f = ERR\n", a);
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/src/calculator_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/src/calculator_impl.h b/remote_services/examples/calculator_service/src/calculator_impl.h
new file mode 100644
index 0000000..5e075e4
--- /dev/null
+++ b/remote_services/examples/calculator_service/src/calculator_impl.h
@@ -0,0 +1,43 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * calculator_impl.h
+ *
+ *  \date       Oct 5, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef CALCULATOR_IMPL_H_
+#define CALCULATOR_IMPL_H_
+
+#include "celix_errno.h"
+
+#include "calculator_service.h"
+
+struct calculator {
+};
+
+celix_status_t calculator_create(calculator_pt *calcuator);
+celix_status_t calculator_destroy(calculator_pt *calcuator);
+celix_status_t calculator_add(calculator_pt calcuator, double a, double b, double *result);
+celix_status_t calculator_sub(calculator_pt calcuator, double a, double b, double *result);
+celix_status_t calculator_sqrt(calculator_pt calcuator, double a, double *result);
+
+#endif /* CALCULATOR_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/CMakeLists.txt b/remote_services/examples/calculator_shell/CMakeLists.txt
index 980fa1a..78c0737 100644
--- a/remote_services/examples/calculator_shell/CMakeLists.txt
+++ b/remote_services/examples/calculator_shell/CMakeLists.txt
@@ -15,28 +15,22 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories("private/include")
-include_directories("../../../utils/public/include")
-include_directories("../calculator_service/public/include")
-
-add_bundle(calculator_shell SOURCES
-    private/src/add_command 
-    private/src/sub_command
-    private/src/sqrt_command
-    private/src/calculator_shell_activator
-    
-    private/include/add_command.h
-    private/include/sqrt_command.h
-    private/include/sub_command.h
-    
+add_bundle(calculator_shell
+    SOURCES
+        src/add_command
+        src/sub_command
+        src/sqrt_command
+        src/calculator_shell_activator
     VERSION 0.0.1
     SYMBOLIC_NAME "apache_celix_remoting_calculator_shell"
 )
+target_include_directories(calculator_shell PRIVATE src)
+target_link_libraries(calculator_shell PRIVATE Celix::shell_api calculator_api)
 
 bundle_files(calculator_shell 
-    ../calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
-    #private/include/org.apache.celix.calc.api.Calculator2.descriptor ##Use this descriptor in case you want to try out versioning!
+    ../calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
+    #src/org.apache.celix.calc.api.Calculator2.descriptor ##Use this descriptor in case you want to try out versioning!
     DESTINATION .
 )
 
-target_link_libraries(calculator_shell PRIVATE Celix::shell_api)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/include/add_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/include/add_command.h b/remote_services/examples/calculator_shell/private/include/add_command.h
deleted file mode 100644
index 58a7bda..0000000
--- a/remote_services/examples/calculator_shell/private/include/add_command.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * add_command.h
- *
- *  \date       Oct 13, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef ADD_COMMAND_H_
-#define ADD_COMMAND_H_
-
-void addCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
-
-#endif /* ADD_COMMAND_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/include/org.apache.celix.calc.api.Calculator2.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/include/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_shell/private/include/org.apache.celix.calc.api.Calculator2.descriptor
deleted file mode 100644
index 789af9a..0000000
--- a/remote_services/examples/calculator_shell/private/include/org.apache.celix.calc.api.Calculator2.descriptor
+++ /dev/null
@@ -1,11 +0,0 @@
-+:header
-+type=interface
-+name=calculator
-+version=1.2.3
-+:annotations
-+classname=org.example.Calculator
-+:types
-+:methods
-+add(DD)D=add(#am=handle;PDD#am=pre;*D)N
-+sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
-+sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/include/sqrt_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/include/sqrt_command.h b/remote_services/examples/calculator_shell/private/include/sqrt_command.h
deleted file mode 100644
index c9d07d2..0000000
--- a/remote_services/examples/calculator_shell/private/include/sqrt_command.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * sqrt_command.h
- *
- *  \date       Oct 13, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef SQRT_COMMAND_H_
-#define SQRT_COMMAND_H_
-
-void sqrtCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
-
-#endif /* SQRT_COMMAND_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/include/sub_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/include/sub_command.h b/remote_services/examples/calculator_shell/private/include/sub_command.h
deleted file mode 100644
index cf13616..0000000
--- a/remote_services/examples/calculator_shell/private/include/sub_command.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * sub_command.h
- *
- *  \date       Oct 13, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef SUB_COMMAND_H_
-#define SUB_COMMAND_H_
-
-void subCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
-
-#endif /* SUB_COMMAND_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/src/add_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/src/add_command.c b/remote_services/examples/calculator_shell/private/src/add_command.c
deleted file mode 100644
index b2520ae..0000000
--- a/remote_services/examples/calculator_shell/private/src/add_command.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * add_command.c
- *
- *  \date       Oct 13, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <command.h>
-
-#include "array_list.h"
-#include "bundle_context.h"
-#include "add_command.h"
-#include "calculator_service.h"
-
-
-static celix_status_t addCommand_isNumeric(char *number, bool *ret);
-
-void addCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
-	celix_status_t status = CELIX_SUCCESS;
-    service_reference_pt calculatorService = NULL;
-
-    status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
-    if (calculatorService == NULL) {
-        fprintf(err, "ADD: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
-        status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
-        if (calculatorService == NULL) {
-            fprintf(err, "ADD: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
-        }
-    }
-    if (status == CELIX_SUCCESS) {
-    	char *token = line;
-    	strtok_r(line, " ", &token);
-	char *aStr = strtok_r(NULL, " ", &token);
-	char *bStr = strtok_r(NULL, " ", &token);
-	bool aNumeric, bNumeric;
-	if (aStr != NULL && bStr != NULL) {
-		addCommand_isNumeric(aStr, &aNumeric);
-		addCommand_isNumeric(bStr, &bNumeric);
-		if(aNumeric && bNumeric){
-			calculator_service_pt calculator = NULL;
-			status = bundleContext_getService(context, calculatorService, (void *) &calculator);
-			if (status == CELIX_SUCCESS && calculator != NULL) {
-				double a = atof(aStr);
-				double b = atof(bStr);
-				double result = 0;
-				status = calculator->add(calculator->calculator, a, b, &result);
-				if (status == CELIX_SUCCESS) {
-					fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", a, b, result);
-				} else {
-					fprintf(err, "ADD: Unexpected exception in Calc service\n");
-				}
-			} else {
-				fprintf(err, "No calc service available\n");
-			}
-		} else {
-			fprintf(err, "ADD: Requires 2 numerical parameter\n");
-		}
-	} else {
-		fprintf(err, "ADD: Requires 2 numerical parameter\n");
-	}
-    } else {
-	fprintf(err, "No calc service available\n");
-    }
-
-    //return status;
-}
-
-static celix_status_t addCommand_isNumeric(char *number, bool *ret) {
-	celix_status_t status = CELIX_SUCCESS;
-	*ret = true;
-	while(*number) {
-		if(!isdigit(*number) && *number != '.') {
-			*ret = false;
-			break;
-		}
-		number++;
-	}
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/src/calculator_shell_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/src/calculator_shell_activator.c b/remote_services/examples/calculator_shell/private/src/calculator_shell_activator.c
deleted file mode 100644
index d6b561b..0000000
--- a/remote_services/examples/calculator_shell/private/src/calculator_shell_activator.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * calculator_shell_activator.c
- *
- *  \date       Oct 13, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <string.h>
-#include <command.h>
-
-#include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
-
-#include "add_command.h"
-#include "sub_command.h"
-#include "sqrt_command.h"
-
-struct activator {
-	service_registration_pt addCommand;
-	command_service_pt addCmd;
-	command_service_pt addCmdSrv;
-
-	service_registration_pt subCommand;
-	command_service_pt subCmd;
-	command_service_pt subCmdSrv;
-
-	service_registration_pt sqrtCommand;
-	command_service_pt sqrtCmd;
-	command_service_pt sqrtCmdSrv;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	if (status == CELIX_SUCCESS) {
-		*userData = calloc(1, sizeof(struct activator));
-		if (!*userData) {
-			status = CELIX_ENOMEM;
-		} else {
-			((struct activator *) (*userData))->addCommand = NULL;
-			((struct activator *) (*userData))->subCommand = NULL;
-			((struct activator *) (*userData))->sqrtCommand = NULL;
-
-			((struct activator *) (*userData))->addCmd = NULL;
-			((struct activator *) (*userData))->subCmd = NULL;
-			((struct activator *) (*userData))->sqrtCmd = NULL;
-
-			((struct activator *) (*userData))->addCmdSrv = NULL;
-			((struct activator *) (*userData))->subCmdSrv = NULL;
-			((struct activator *) (*userData))->sqrtCmdSrv = NULL;
-		}
-	}
-
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-    celix_status_t status = CELIX_SUCCESS;
-
-	struct activator * activator = (struct activator *) userData;
-
-	activator->addCmdSrv = calloc(1, sizeof(*activator->addCmdSrv));
-	activator->addCmdSrv->handle = context;
-	activator->addCmdSrv->executeCommand = (void *)addCommand_execute;
-	properties_pt props = properties_create();
-	properties_set(props, OSGI_SHELL_COMMAND_NAME, "add");
-	bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->addCmdSrv, props, &activator->addCommand);
-
-
-	activator->sqrtCmdSrv = calloc(1, sizeof(*activator->sqrtCmdSrv));
-	activator->sqrtCmdSrv->handle = context;
-	activator->sqrtCmdSrv->executeCommand = (void *)sqrtCommand_execute;
-	props = properties_create();
-	properties_set(props, OSGI_SHELL_COMMAND_NAME, "sqrt");
-	bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->sqrtCmdSrv, props, &activator->sqrtCommand);
-
-	activator->subCmdSrv = calloc(1, sizeof(*activator->subCmdSrv));
-	activator->subCmdSrv->handle = context;
-	activator->subCmdSrv->executeCommand = (void *)subCommand_execute;
-	props = properties_create();
-	properties_set(props, OSGI_SHELL_COMMAND_NAME, "sub");
-	bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->subCmdSrv, props, &activator->subCommand);
-
-	return status;
-}
-
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-    celix_status_t status = CELIX_SUCCESS;
-	struct activator * activator = (struct activator *) userData;
-	serviceRegistration_unregister(activator->addCommand);
-	serviceRegistration_unregister(activator->subCommand);
-	serviceRegistration_unregister(activator->sqrtCommand);
-
-	free(activator->addCmdSrv);
-	free(activator->subCmdSrv);
-	free(activator->sqrtCmdSrv);
-
-	return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	free(userData);
-	return CELIX_SUCCESS;
-}
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/src/sqrt_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/src/sqrt_command.c b/remote_services/examples/calculator_shell/private/src/sqrt_command.c
deleted file mode 100644
index 2e7238c..0000000
--- a/remote_services/examples/calculator_shell/private/src/sqrt_command.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * sqrt_command.c
- *
- *  \date       Oct 13, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "array_list.h"
-#include "bundle_context.h"
-#include "sqrt_command.h"
-#include "calculator_service.h"
-
-static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret);
-
-void sqrtCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
-	celix_status_t status = CELIX_SUCCESS;
-    service_reference_pt calculatorService = NULL;
-
-    status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
-    if (calculatorService == NULL) {
-        fprintf(err, "SQRT: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
-        status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
-        if (calculatorService == NULL) {
-            fprintf(err, "SQRT: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
-        }
-    }
-    if (status == CELIX_SUCCESS) {
-    	char *token = line;
-    	strtok_r(line, " ", &token);
-		char *aStr = strtok_r(NULL, " ", &token);
-		if(aStr != NULL){
-			bool numeric;
-			sqrtCommand_isNumeric(aStr, &numeric);
-			if (numeric) {
-				calculator_service_pt calculator = NULL;
-				status = bundleContext_getService(context, calculatorService, (void *) &calculator);
-				if (status == CELIX_SUCCESS && calculator != NULL) {
-					double a = atof(aStr);
-					double result = 0;
-					status = calculator->sqrt(calculator->calculator, a, &result);
-					if (status == CELIX_SUCCESS) {
-						fprintf(out, "CALCULATOR_SHELL: Sqrt: %f = %f\n", a, result);
-					} else {
-						fprintf(err, "SQRT: Unexpected exception in Calc service\n");
-					}
-				} else {
-					fprintf(err, "No calc service available\n");
-				}
-			} else {
-				fprintf(err, "SQRT: Requires 1 numerical parameter\n");
-			}
-		} else {
-			fprintf(err, "SQRT: Requires 1 numerical parameter\n");
-		}
-    } else {
-		fprintf(err, "No calc service available\n");
-    }
-
-    //return status;
-}
-
-static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret) {
-	celix_status_t status = CELIX_SUCCESS;
-	*ret = true;
-	while(*number) {
-		if(!isdigit(*number) && *number != '.') {
-			*ret = false;
-			break;
-		}
-		number++;
-	}
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/src/sub_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/src/sub_command.c b/remote_services/examples/calculator_shell/private/src/sub_command.c
deleted file mode 100644
index 672ea4c..0000000
--- a/remote_services/examples/calculator_shell/private/src/sub_command.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * sub_command.c
- *
- *  \date       Oct 13, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "array_list.h"
-#include "bundle_context.h"
-#include "sub_command.h"
-#include "calculator_service.h"
-
-static celix_status_t subCommand_isNumeric(char *number, bool *ret);
-
-void subCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
-	celix_status_t status = CELIX_SUCCESS;
-    service_reference_pt calculatorService = NULL;
-
-    status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
-    if (calculatorService == NULL) {
-        fprintf(err, "SUB: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
-        status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
-        if (calculatorService == NULL) {
-            fprintf(err, "SUB: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
-        }
-    }
-    if (status == CELIX_SUCCESS) {
-    	char *token = line;
-    	strtok_r(line, " ", &token);
-		char *aStr = strtok_r(NULL, " ", &token);
-		char *bStr = strtok_r(NULL, " ", &token);
-		if(aStr != NULL && bStr != NULL ){
-			bool aNumeric, bNumeric;
-			subCommand_isNumeric(aStr, &aNumeric);
-			subCommand_isNumeric(bStr, &bNumeric);
-			if (aNumeric && bNumeric) {
-				calculator_service_pt calculator = NULL;
-				status = bundleContext_getService(context, calculatorService, (void *) &calculator);
-				if (status == CELIX_SUCCESS && calculator != NULL) {
-					double a = atof(aStr);
-					double b = atof(bStr);
-					double result = 0;
-					status = calculator->sub(calculator->calculator, a, b, &result);
-					if (status == CELIX_SUCCESS) {
-						fprintf(out, "CALCULATOR_SHELL: Sub: %f - %f = %f\n", a, b, result);
-					} else {
-						fprintf(err, "SUB: Unexpected exception in Calc service\n");
-					}
-				} else {
-					fprintf(err, "No calc service available\n");
-				}
-			} else {
-				fprintf(err, "SUB: Requires 2 numerical parameter\n");
-			}
-		} else {
-			fprintf(err, "SUB: Requires 2 numerical parameter\n");
-		}
-    } else {
-		fprintf(err, "No calc service available\n");
-    }
-
-    //return status;
-}
-
-static celix_status_t subCommand_isNumeric(char *number, bool *ret) {
-	celix_status_t status = CELIX_SUCCESS;
-	*ret = true;
-	while(*number) {
-		if(!isdigit(*number) && *number != '.') {
-			*ret = false;
-			break;
-		}
-		number++;
-	}
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/add_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/add_command.c b/remote_services/examples/calculator_shell/src/add_command.c
new file mode 100644
index 0000000..b2520ae
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/add_command.c
@@ -0,0 +1,101 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * add_command.c
+ *
+ *  \date       Oct 13, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <command.h>
+
+#include "array_list.h"
+#include "bundle_context.h"
+#include "add_command.h"
+#include "calculator_service.h"
+
+
+static celix_status_t addCommand_isNumeric(char *number, bool *ret);
+
+void addCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
+	celix_status_t status = CELIX_SUCCESS;
+    service_reference_pt calculatorService = NULL;
+
+    status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
+    if (calculatorService == NULL) {
+        fprintf(err, "ADD: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
+        status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
+        if (calculatorService == NULL) {
+            fprintf(err, "ADD: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
+        }
+    }
+    if (status == CELIX_SUCCESS) {
+    	char *token = line;
+    	strtok_r(line, " ", &token);
+	char *aStr = strtok_r(NULL, " ", &token);
+	char *bStr = strtok_r(NULL, " ", &token);
+	bool aNumeric, bNumeric;
+	if (aStr != NULL && bStr != NULL) {
+		addCommand_isNumeric(aStr, &aNumeric);
+		addCommand_isNumeric(bStr, &bNumeric);
+		if(aNumeric && bNumeric){
+			calculator_service_pt calculator = NULL;
+			status = bundleContext_getService(context, calculatorService, (void *) &calculator);
+			if (status == CELIX_SUCCESS && calculator != NULL) {
+				double a = atof(aStr);
+				double b = atof(bStr);
+				double result = 0;
+				status = calculator->add(calculator->calculator, a, b, &result);
+				if (status == CELIX_SUCCESS) {
+					fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", a, b, result);
+				} else {
+					fprintf(err, "ADD: Unexpected exception in Calc service\n");
+				}
+			} else {
+				fprintf(err, "No calc service available\n");
+			}
+		} else {
+			fprintf(err, "ADD: Requires 2 numerical parameter\n");
+		}
+	} else {
+		fprintf(err, "ADD: Requires 2 numerical parameter\n");
+	}
+    } else {
+	fprintf(err, "No calc service available\n");
+    }
+
+    //return status;
+}
+
+static celix_status_t addCommand_isNumeric(char *number, bool *ret) {
+	celix_status_t status = CELIX_SUCCESS;
+	*ret = true;
+	while(*number) {
+		if(!isdigit(*number) && *number != '.') {
+			*ret = false;
+			break;
+		}
+		number++;
+	}
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/add_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/add_command.h b/remote_services/examples/calculator_shell/src/add_command.h
new file mode 100644
index 0000000..58a7bda
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/add_command.h
@@ -0,0 +1,32 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * add_command.h
+ *
+ *  \date       Oct 13, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef ADD_COMMAND_H_
+#define ADD_COMMAND_H_
+
+void addCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
+
+#endif /* ADD_COMMAND_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/calculator_shell_activator.c b/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
new file mode 100644
index 0000000..d6b561b
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
@@ -0,0 +1,125 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * calculator_shell_activator.c
+ *
+ *  \date       Oct 13, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <command.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+
+#include "add_command.h"
+#include "sub_command.h"
+#include "sqrt_command.h"
+
+struct activator {
+	service_registration_pt addCommand;
+	command_service_pt addCmd;
+	command_service_pt addCmdSrv;
+
+	service_registration_pt subCommand;
+	command_service_pt subCmd;
+	command_service_pt subCmdSrv;
+
+	service_registration_pt sqrtCommand;
+	command_service_pt sqrtCmd;
+	command_service_pt sqrtCmdSrv;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	if (status == CELIX_SUCCESS) {
+		*userData = calloc(1, sizeof(struct activator));
+		if (!*userData) {
+			status = CELIX_ENOMEM;
+		} else {
+			((struct activator *) (*userData))->addCommand = NULL;
+			((struct activator *) (*userData))->subCommand = NULL;
+			((struct activator *) (*userData))->sqrtCommand = NULL;
+
+			((struct activator *) (*userData))->addCmd = NULL;
+			((struct activator *) (*userData))->subCmd = NULL;
+			((struct activator *) (*userData))->sqrtCmd = NULL;
+
+			((struct activator *) (*userData))->addCmdSrv = NULL;
+			((struct activator *) (*userData))->subCmdSrv = NULL;
+			((struct activator *) (*userData))->sqrtCmdSrv = NULL;
+		}
+	}
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+    celix_status_t status = CELIX_SUCCESS;
+
+	struct activator * activator = (struct activator *) userData;
+
+	activator->addCmdSrv = calloc(1, sizeof(*activator->addCmdSrv));
+	activator->addCmdSrv->handle = context;
+	activator->addCmdSrv->executeCommand = (void *)addCommand_execute;
+	properties_pt props = properties_create();
+	properties_set(props, OSGI_SHELL_COMMAND_NAME, "add");
+	bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->addCmdSrv, props, &activator->addCommand);
+
+
+	activator->sqrtCmdSrv = calloc(1, sizeof(*activator->sqrtCmdSrv));
+	activator->sqrtCmdSrv->handle = context;
+	activator->sqrtCmdSrv->executeCommand = (void *)sqrtCommand_execute;
+	props = properties_create();
+	properties_set(props, OSGI_SHELL_COMMAND_NAME, "sqrt");
+	bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->sqrtCmdSrv, props, &activator->sqrtCommand);
+
+	activator->subCmdSrv = calloc(1, sizeof(*activator->subCmdSrv));
+	activator->subCmdSrv->handle = context;
+	activator->subCmdSrv->executeCommand = (void *)subCommand_execute;
+	props = properties_create();
+	properties_set(props, OSGI_SHELL_COMMAND_NAME, "sub");
+	bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->subCmdSrv, props, &activator->subCommand);
+
+	return status;
+}
+
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+    celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = (struct activator *) userData;
+	serviceRegistration_unregister(activator->addCommand);
+	serviceRegistration_unregister(activator->subCommand);
+	serviceRegistration_unregister(activator->sqrtCommand);
+
+	free(activator->addCmdSrv);
+	free(activator->subCmdSrv);
+	free(activator->sqrtCmdSrv);
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	free(userData);
+	return CELIX_SUCCESS;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator2.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator2.descriptor
new file mode 100644
index 0000000..789af9a
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator2.descriptor
@@ -0,0 +1,11 @@
++:header
++type=interface
++name=calculator
++version=1.2.3
++:annotations
++classname=org.example.Calculator
++:types
++:methods
++add(DD)D=add(#am=handle;PDD#am=pre;*D)N
++sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
++sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/sqrt_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/sqrt_command.c b/remote_services/examples/calculator_shell/src/sqrt_command.c
new file mode 100644
index 0000000..2e7238c
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/sqrt_command.c
@@ -0,0 +1,96 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * sqrt_command.c
+ *
+ *  \date       Oct 13, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "array_list.h"
+#include "bundle_context.h"
+#include "sqrt_command.h"
+#include "calculator_service.h"
+
+static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret);
+
+void sqrtCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
+	celix_status_t status = CELIX_SUCCESS;
+    service_reference_pt calculatorService = NULL;
+
+    status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
+    if (calculatorService == NULL) {
+        fprintf(err, "SQRT: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
+        status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
+        if (calculatorService == NULL) {
+            fprintf(err, "SQRT: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
+        }
+    }
+    if (status == CELIX_SUCCESS) {
+    	char *token = line;
+    	strtok_r(line, " ", &token);
+		char *aStr = strtok_r(NULL, " ", &token);
+		if(aStr != NULL){
+			bool numeric;
+			sqrtCommand_isNumeric(aStr, &numeric);
+			if (numeric) {
+				calculator_service_pt calculator = NULL;
+				status = bundleContext_getService(context, calculatorService, (void *) &calculator);
+				if (status == CELIX_SUCCESS && calculator != NULL) {
+					double a = atof(aStr);
+					double result = 0;
+					status = calculator->sqrt(calculator->calculator, a, &result);
+					if (status == CELIX_SUCCESS) {
+						fprintf(out, "CALCULATOR_SHELL: Sqrt: %f = %f\n", a, result);
+					} else {
+						fprintf(err, "SQRT: Unexpected exception in Calc service\n");
+					}
+				} else {
+					fprintf(err, "No calc service available\n");
+				}
+			} else {
+				fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+			}
+		} else {
+			fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+		}
+    } else {
+		fprintf(err, "No calc service available\n");
+    }
+
+    //return status;
+}
+
+static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret) {
+	celix_status_t status = CELIX_SUCCESS;
+	*ret = true;
+	while(*number) {
+		if(!isdigit(*number) && *number != '.') {
+			*ret = false;
+			break;
+		}
+		number++;
+	}
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/sqrt_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/sqrt_command.h b/remote_services/examples/calculator_shell/src/sqrt_command.h
new file mode 100644
index 0000000..c9d07d2
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/sqrt_command.h
@@ -0,0 +1,32 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * sqrt_command.h
+ *
+ *  \date       Oct 13, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef SQRT_COMMAND_H_
+#define SQRT_COMMAND_H_
+
+void sqrtCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
+
+#endif /* SQRT_COMMAND_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/sub_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/sub_command.c b/remote_services/examples/calculator_shell/src/sub_command.c
new file mode 100644
index 0000000..672ea4c
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/sub_command.c
@@ -0,0 +1,99 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * sub_command.c
+ *
+ *  \date       Oct 13, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "array_list.h"
+#include "bundle_context.h"
+#include "sub_command.h"
+#include "calculator_service.h"
+
+static celix_status_t subCommand_isNumeric(char *number, bool *ret);
+
+void subCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
+	celix_status_t status = CELIX_SUCCESS;
+    service_reference_pt calculatorService = NULL;
+
+    status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
+    if (calculatorService == NULL) {
+        fprintf(err, "SUB: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
+        status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
+        if (calculatorService == NULL) {
+            fprintf(err, "SUB: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
+        }
+    }
+    if (status == CELIX_SUCCESS) {
+    	char *token = line;
+    	strtok_r(line, " ", &token);
+		char *aStr = strtok_r(NULL, " ", &token);
+		char *bStr = strtok_r(NULL, " ", &token);
+		if(aStr != NULL && bStr != NULL ){
+			bool aNumeric, bNumeric;
+			subCommand_isNumeric(aStr, &aNumeric);
+			subCommand_isNumeric(bStr, &bNumeric);
+			if (aNumeric && bNumeric) {
+				calculator_service_pt calculator = NULL;
+				status = bundleContext_getService(context, calculatorService, (void *) &calculator);
+				if (status == CELIX_SUCCESS && calculator != NULL) {
+					double a = atof(aStr);
+					double b = atof(bStr);
+					double result = 0;
+					status = calculator->sub(calculator->calculator, a, b, &result);
+					if (status == CELIX_SUCCESS) {
+						fprintf(out, "CALCULATOR_SHELL: Sub: %f - %f = %f\n", a, b, result);
+					} else {
+						fprintf(err, "SUB: Unexpected exception in Calc service\n");
+					}
+				} else {
+					fprintf(err, "No calc service available\n");
+				}
+			} else {
+				fprintf(err, "SUB: Requires 2 numerical parameter\n");
+			}
+		} else {
+			fprintf(err, "SUB: Requires 2 numerical parameter\n");
+		}
+    } else {
+		fprintf(err, "No calc service available\n");
+    }
+
+    //return status;
+}
+
+static celix_status_t subCommand_isNumeric(char *number, bool *ret) {
+	celix_status_t status = CELIX_SUCCESS;
+	*ret = true;
+	while(*number) {
+		if(!isdigit(*number) && *number != '.') {
+			*ret = false;
+			break;
+		}
+		number++;
+	}
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/sub_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/sub_command.h b/remote_services/examples/calculator_shell/src/sub_command.h
new file mode 100644
index 0000000..cf13616
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/sub_command.h
@@ -0,0 +1,32 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * sub_command.h
+ *
+ *  \date       Oct 13, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef SUB_COMMAND_H_
+#define SUB_COMMAND_H_
+
+void subCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
+
+#endif /* SUB_COMMAND_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/CMakeLists.txt b/remote_services/remote_service_admin/CMakeLists.txt
deleted file mode 100644
index ac703e2..0000000
--- a/remote_services/remote_service_admin/CMakeLists.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-install (FILES 
-        public/include/remote_endpoint_impl.h
-        public/include/remote_endpoint.h
-        public/include/remote_proxy.h
-        public/include/remote_service_admin.h
-        public/include/export_registration.h
-        public/include/import_registration.h
-        public/include/endpoint_description.h
-        public/include/endpoint_listener.h
-        public/include/remote_constants.h
-    DESTINATION 
-        include/celix/remote_service_admin 
-    COMPONENT 
-        remote_service_admin
-)
-install (FILES
-        private/src/remote_proxy_factory_impl.c
-    DESTINATION
-        share/celix/remote_service_admin
-    COMPONENT
-        remote_service_admin
-)
-install (FILES 
-        public/include/endpoint_listener.h
-    DESTINATION 
-        include/celix/endpoint_listener 
-    COMPONENT 
-        remote_service_admin
-)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/README.md
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/README.md b/remote_services/remote_service_admin/README.md
deleted file mode 100644
index c4bdebd..0000000
--- a/remote_services/remote_service_admin/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-## Remote Service Admin
-
-The Remote Service Admin (RSA) provides the mechanisms to import and export services when instructed to do so by the Topology Manager. 
-
-To delegate method calls to the actual service implementation, the RSA_SHM and the RSA_HTTP are using "endpoint/proxy" bundles, which has all the knowledge about the marshalling and unmarshalling of data for the service. The RSA_DFI implementation combines a [foreign function interface](https://en.wikipedia.org/wiki/Foreign_function_interface) technique together with manualy created descriptors.  
-
-Note that this folder contains code commonly used by the RSA implementations and therefore does not include any CMAKE configuration.
-
-###### Properties
-    ENDPOINTS				 defines the relative directory where endpoints and proxys can be found (default: endpoints)
-    CELIX_FRAMEWORK_EXTENDER_PATH  Used in RSA_DFI only. Can be used to define a path to use as an extender path point for the framework bundle. For normal bundles the bundle cache is used. 

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/private/include/export_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/include/export_registration_impl.h b/remote_services/remote_service_admin/private/include/export_registration_impl.h
deleted file mode 100644
index bb276f9..0000000
--- a/remote_services/remote_service_admin/private/include/export_registration_impl.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * export_registration_impl.h
- *
- *  \date       Oct 6, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef EXPORT_REGISTRATION_IMPL_H_
-#define EXPORT_REGISTRATION_IMPL_H_
-
-#include "remote_service_admin.h"
-#include "remote_endpoint.h"
-#include "service_tracker.h"
-#include "log_helper.h"
-
-struct export_registration {
-	bundle_context_pt context;
-	remote_service_admin_pt rsa;
-	endpoint_description_pt endpointDescription;
-	service_reference_pt reference;
-	log_helper_pt loghelper;
-
-	service_tracker_pt tracker;
-	service_tracker_pt endpointTracker;
-
-	remote_endpoint_service_pt endpoint;
-
-	export_reference_pt exportReference;
-	bundle_pt bundle;
-
-	bool closed;
-};
-
-celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration);
-celix_status_t exportRegistration_destroy(export_registration_pt *registration);
-celix_status_t exportRegistration_open(export_registration_pt registration);
-
-celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription);
-celix_status_t exportRegistration_startTracking(export_registration_pt registration);
-celix_status_t exportRegistration_stopTracking(export_registration_pt registration);
-
-#endif /* EXPORT_REGISTRATION_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/private/include/import_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/include/import_registration_impl.h b/remote_services/remote_service_admin/private/include/import_registration_impl.h
deleted file mode 100644
index 7aa397f..0000000
--- a/remote_services/remote_service_admin/private/include/import_registration_impl.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * import_registration_impl.h
- *
- *  \date       Oct 14, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef IMPORT_REGISTRATION_IMPL_H_
-#define IMPORT_REGISTRATION_IMPL_H_
-
-#include "remote_service_admin.h"
-#include "remote_proxy.h"
-#include "service_tracker.h"
-#include "log_helper.h"
-
-struct import_registration {
-	bundle_context_pt context;
-	endpoint_description_pt endpointDescription;
-
-	service_reference_pt reference;
-	import_reference_pt importReference;
-
-	remote_service_admin_pt rsa;
-	sendToHandle sendToCallback;
-
-	bool closed;
-};
-
-
-
-struct import_registration_factory
-{
-	char* serviceName;
-	log_helper_pt loghelper;
-	remote_proxy_factory_service_pt trackedFactory;
-	service_tracker_pt proxyFactoryTracker;
-	bundle_context_pt context;
-	array_list_pt registrations;
-	bundle_pt bundle;
-};
-
-
-celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle callback, bundle_context_pt context, import_registration_pt *registration);
-celix_status_t importRegistration_destroy(import_registration_pt registration);
-
-celix_status_t importRegistration_setEndpointDescription(import_registration_pt registration, endpoint_description_pt endpointDescription);
-celix_status_t importRegistration_setHandler(import_registration_pt registration, void * handler);
-celix_status_t importRegistration_setCallback(import_registration_pt registration, sendToHandle callback);
-
-celix_status_t importRegistration_getException(import_registration_pt registration);
-celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference);
-
-celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker);
-
-celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory);
-//celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory);
-celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory);
-celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory);
-
-
-
-#endif /* IMPORT_REGISTRATION_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h b/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
deleted file mode 100644
index e8a5e1f..0000000
--- a/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_impl.h
- *
- *  \date       Dec 5, 2013
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_IMPL_H_
-#define REMOTE_SERVICE_ADMIN_IMPL_H_
-
-#include "remote_service_admin.h"
-
-#define BUNDLE_STORE_PROPERTY_NAME "ENDPOINTS"
-#define DEFAULT_BUNDLE_STORE "endpoints"
-
-celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
-celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
-
-celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *methodSignature, char **reply, int* replyStatus);
-
-celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
-celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration);
-celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
-celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
-celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
-celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
-
-celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
-
-#endif /* REMOTE_SERVICE_ADMIN_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/private/src/endpoint_description.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/src/endpoint_description.c b/remote_services/remote_service_admin/private/src/endpoint_description.c
deleted file mode 100644
index 0d8b684..0000000
--- a/remote_services/remote_service_admin/private/src/endpoint_description.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_description.c
- *
- *  \date       25 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <string.h>
-
-#include "celix_errno.h"
-#include "celix_log.h"
-
-#include "endpoint_description.h"
-#include "remote_constants.h"
-#include "constants.h"
-
-static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty);
-
-celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	unsigned long serviceId = 0UL;
-	status = endpointDescription_verifyLongProperty(properties, (char *) OSGI_RSA_ENDPOINT_SERVICE_ID, &serviceId);
-	if (status != CELIX_SUCCESS) {
-		return status;
-	}
-
-	endpoint_description_pt ep = calloc(1,sizeof(*ep));
-
-    ep->properties = properties;
-    ep->frameworkUUID = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
-    ep->id = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_ID);
-    ep->service = strndup(properties_get(properties, OSGI_FRAMEWORK_OBJECTCLASS), 1024*10);
-    ep->serviceId = serviceId;
-
-    if (!(ep->frameworkUUID) || !(ep->id) || !(ep->service) ) {
-    	fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "ENDPOINT_DESCRIPTION: incomplete description!.");
-    	status = CELIX_BUNDLE_EXCEPTION;
-    }
-
-    if(status == CELIX_SUCCESS){
-	*endpointDescription = ep;
-    }
-    else{
-	*endpointDescription = NULL;
-	free(ep);
-    }
-
-    return status;
-}
-
-celix_status_t endpointDescription_destroy(endpoint_description_pt description) {
-    properties_destroy(description->properties);
-    free(description->service);
-    free(description);
-    return CELIX_SUCCESS;
-}
-
-static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char *value = properties_get(properties, propertyName);
-    if (value == NULL) {
-        *longProperty = 0UL;
-    } else {
-        *longProperty = strtoul(value,NULL,10);
-    }
-
-    return status;
-}


[10/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/private/include/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/private/include/discovery_impl.h b/remote_services/discovery_configured/private/include/discovery_impl.h
deleted file mode 100644
index 0414eac..0000000
--- a/remote_services/discovery_configured/private/include/discovery_impl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * discovery_impl.h
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef DISCOVERY_IMPL_H_
-#define DISCOVERY_IMPL_H_
-
-#include "bundle_context.h"
-#include "service_reference.h"
-
-#include "endpoint_description.h"
-#include "endpoint_listener.h"
-
-#include "endpoint_discovery_poller.h"
-#include "endpoint_discovery_server.h"
-
-#include "log_helper.h"
-
-#define DEFAULT_SERVER_IP 	"127.0.0.1"
-#define DEFAULT_SERVER_PORT "9999"
-#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.configured"
-#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.configured"
-
-
-struct discovery {
-	bundle_context_pt context;
-
-	celix_thread_mutex_t listenerReferencesMutex;
-	celix_thread_mutex_t discoveredServicesMutex;
-
-	hash_map_pt listenerReferences; //key=serviceReference, value=nop
-	hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
-
-	endpoint_discovery_poller_pt poller;
-	endpoint_discovery_server_pt server;
-
-	log_helper_pt loghelper;
-};
-
-#endif /* DISCOVERY_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/private/src/desc.xml
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/private/src/desc.xml b/remote_services/discovery_configured/private/src/desc.xml
deleted file mode 100644
index 5998992..0000000
--- a/remote_services/discovery_configured/private/src/desc.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- -->
-<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
-	<endpoint-description>
-		<property name="service.intents">
-			<list>
-				<value>SOAP</value>
-				<value>HTTP</value>
-			</list>
-		</property>
-		<property name="endpoint.id" value="http://ws.acme.com:9000/hello" />
-		<property name="objectClass" value="com.acme.Foo" />
-		<property name="endpoint.package.version.com.acme" value="4.2" />
-		<property name="service.imported.configs" value="com.acme" />
-		<property name="com.acme.ws.xml">
-			<xml>
-				<config xmlns="http://acme.com/defs">
-					<port>1029</port>
-					<host>www.acme.com</host>
-				</config>
-			</xml>
-		</property>
-	</endpoint-description>
-</endpoint-descriptions>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/private/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/private/src/discovery_impl.c b/remote_services/discovery_configured/private/src/discovery_impl.c
deleted file mode 100644
index 35a0c71..0000000
--- a/remote_services/discovery_configured/private/src/discovery_impl.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery_impl.c
- *
- * \date        Aug 8, 2014
- * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright	Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <netdb.h>
-
-#include "celix_threads.h"
-#include "bundle_context.h"
-#include "utils.h"
-#include "log_helper.h"
-
-#include "discovery.h"
-#include "discovery_impl.h"
-
-
-celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
-	celix_status_t status;
-
-	*discovery = malloc(sizeof(struct discovery));
-	if (!*discovery) {
-		status = CELIX_ENOMEM;
-	}
-	else {
-		(*discovery)->context = context;
-		(*discovery)->poller = NULL;
-		(*discovery)->server = NULL;
-
-		(*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
-		(*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-		status = celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
-		status = celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
-
-		logHelper_create(context, &(*discovery)->loghelper);
-	}
-
-	return status;
-}
-
-celix_status_t discovery_start(discovery_pt discovery) {
-    celix_status_t status;
-
-	logHelper_start(discovery->loghelper);
-
-    status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
-    if (status != CELIX_SUCCESS) {
-    	return CELIX_BUNDLE_EXCEPTION;
-    }
-
-    status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
-    if (status != CELIX_SUCCESS) {
-    	return CELIX_BUNDLE_EXCEPTION;
-    }
-
-    return status;
-}
-
-celix_status_t discovery_stop(discovery_pt discovery) {
-	celix_status_t status;
-
-	status = endpointDiscoveryServer_destroy(discovery->server);
-	status = endpointDiscoveryPoller_destroy(discovery->poller);
-
-	logHelper_stop(discovery->loghelper);
-
-	return status;
-}
-
-celix_status_t discovery_destroy(discovery_pt discovery) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	discovery->context = NULL;
-	discovery->poller = NULL;
-	discovery->server = NULL;
-
-	celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
-	hashMap_destroy(discovery->discoveredServices, false, false);
-	discovery->discoveredServices = NULL;
-
-	celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
-	celixThreadMutex_destroy(&discovery->discoveredServicesMutex);
-
-	celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
-	hashMap_destroy(discovery->listenerReferences, false, false);
-	discovery->listenerReferences = NULL;
-
-	celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
-
-	celixThreadMutex_destroy(&discovery->listenerReferencesMutex);
-
-	logHelper_destroy(&discovery->loghelper);
-
-	free(discovery);
-
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/src/desc.xml
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/src/desc.xml b/remote_services/discovery_configured/src/desc.xml
new file mode 100644
index 0000000..5998992
--- /dev/null
+++ b/remote_services/discovery_configured/src/desc.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ -->
+<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
+	<endpoint-description>
+		<property name="service.intents">
+			<list>
+				<value>SOAP</value>
+				<value>HTTP</value>
+			</list>
+		</property>
+		<property name="endpoint.id" value="http://ws.acme.com:9000/hello" />
+		<property name="objectClass" value="com.acme.Foo" />
+		<property name="endpoint.package.version.com.acme" value="4.2" />
+		<property name="service.imported.configs" value="com.acme" />
+		<property name="com.acme.ws.xml">
+			<xml>
+				<config xmlns="http://acme.com/defs">
+					<port>1029</port>
+					<host>www.acme.com</host>
+				</config>
+			</xml>
+		</property>
+	</endpoint-description>
+</endpoint-descriptions>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/src/discovery_impl.c b/remote_services/discovery_configured/src/discovery_impl.c
new file mode 100644
index 0000000..35a0c71
--- /dev/null
+++ b/remote_services/discovery_configured/src/discovery_impl.c
@@ -0,0 +1,123 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery_impl.c
+ *
+ * \date        Aug 8, 2014
+ * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <netdb.h>
+
+#include "celix_threads.h"
+#include "bundle_context.h"
+#include "utils.h"
+#include "log_helper.h"
+
+#include "discovery.h"
+#include "discovery_impl.h"
+
+
+celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
+	celix_status_t status;
+
+	*discovery = malloc(sizeof(struct discovery));
+	if (!*discovery) {
+		status = CELIX_ENOMEM;
+	}
+	else {
+		(*discovery)->context = context;
+		(*discovery)->poller = NULL;
+		(*discovery)->server = NULL;
+
+		(*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+		(*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+		status = celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
+		status = celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
+
+		logHelper_create(context, &(*discovery)->loghelper);
+	}
+
+	return status;
+}
+
+celix_status_t discovery_start(discovery_pt discovery) {
+    celix_status_t status;
+
+	logHelper_start(discovery->loghelper);
+
+    status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
+    if (status != CELIX_SUCCESS) {
+    	return CELIX_BUNDLE_EXCEPTION;
+    }
+
+    status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
+    if (status != CELIX_SUCCESS) {
+    	return CELIX_BUNDLE_EXCEPTION;
+    }
+
+    return status;
+}
+
+celix_status_t discovery_stop(discovery_pt discovery) {
+	celix_status_t status;
+
+	status = endpointDiscoveryServer_destroy(discovery->server);
+	status = endpointDiscoveryPoller_destroy(discovery->poller);
+
+	logHelper_stop(discovery->loghelper);
+
+	return status;
+}
+
+celix_status_t discovery_destroy(discovery_pt discovery) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	discovery->context = NULL;
+	discovery->poller = NULL;
+	discovery->server = NULL;
+
+	celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+	hashMap_destroy(discovery->discoveredServices, false, false);
+	discovery->discoveredServices = NULL;
+
+	celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+	celixThreadMutex_destroy(&discovery->discoveredServicesMutex);
+
+	celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+	hashMap_destroy(discovery->listenerReferences, false, false);
+	discovery->listenerReferences = NULL;
+
+	celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+
+	celixThreadMutex_destroy(&discovery->listenerReferencesMutex);
+
+	logHelper_destroy(&discovery->loghelper);
+
+	free(discovery);
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/src/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/src/discovery_impl.h b/remote_services/discovery_configured/src/discovery_impl.h
new file mode 100644
index 0000000..0414eac
--- /dev/null
+++ b/remote_services/discovery_configured/src/discovery_impl.h
@@ -0,0 +1,62 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * discovery_impl.h
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef DISCOVERY_IMPL_H_
+#define DISCOVERY_IMPL_H_
+
+#include "bundle_context.h"
+#include "service_reference.h"
+
+#include "endpoint_description.h"
+#include "endpoint_listener.h"
+
+#include "endpoint_discovery_poller.h"
+#include "endpoint_discovery_server.h"
+
+#include "log_helper.h"
+
+#define DEFAULT_SERVER_IP 	"127.0.0.1"
+#define DEFAULT_SERVER_PORT "9999"
+#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.configured"
+#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.configured"
+
+
+struct discovery {
+	bundle_context_pt context;
+
+	celix_thread_mutex_t listenerReferencesMutex;
+	celix_thread_mutex_t discoveredServicesMutex;
+
+	hash_map_pt listenerReferences; //key=serviceReference, value=nop
+	hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
+
+	endpoint_discovery_poller_pt poller;
+	endpoint_discovery_server_pt server;
+
+	log_helper_pt loghelper;
+};
+
+#endif /* DISCOVERY_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_etcd/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_etcd/CMakeLists.txt b/remote_services/discovery_etcd/CMakeLists.txt
index b8955de..4168281 100644
--- a/remote_services/discovery_etcd/CMakeLists.txt
+++ b/remote_services/discovery_etcd/CMakeLists.txt
@@ -20,42 +20,19 @@ if (RSA_DISCOVERY_ETCD)
 	find_package(CURL REQUIRED)
 	find_package(LibXml2 REQUIRED)
 	find_package(Jansson REQUIRED)
-	
-	include_directories("${CURL_INCLUDE_DIR}")
-	include_directories("${JANSSON_INCLUDE_DIR}")
-	include_directories("${LIBXML2_INCLUDE_DIR}")
-	include_directories("${PROJECT_SOURCE_DIR}/etcdlib/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery/private/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery_etcd/private/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-	include_directories("private/include")
     
 	add_bundle(discovery_etcd 
         VERSION 0.9.0
         SYMBOLIC_NAME "apache_celix_rsa_discovery_etcd"
         NAME "Apache Celix RSA Discovery ETCD"
         SOURCES
-		src/discovery_impl.c
-	    src/etcd_watcher.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery_activator.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_reader.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_writer.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_poller.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_server.c
-	    ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
-	    ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
+			src/discovery_impl.c
+	    	src/etcd_watcher.c
 	)
 	target_link_libraries(discovery_etcd PRIVATE Celix::log_helper)
-	target_include_directories(discovery_etcd PRIVATE src ../discovery/private/include)
+	target_include_directories(discovery_etcd PRIVATE src )
+	target_include_directories(discovery_etcd PRIVATE ${CURL_INCLUDE_DIR} ${JANSSON_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
+	target_link_libraries(discovery_etcd PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} ${JANSSON_LIBRARIES} discovery_common)
 
 	install_bundle(discovery_etcd)
-		
-	target_link_libraries(discovery_etcd PRIVATE Celix::etcdlib ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} ${JANSSON_LIBRARIES})
-
 endif (RSA_DISCOVERY_ETCD)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/CMakeLists.txt b/remote_services/discovery_shm/CMakeLists.txt
index 862096c..dff403d 100644
--- a/remote_services/discovery_shm/CMakeLists.txt
+++ b/remote_services/discovery_shm/CMakeLists.txt
@@ -19,40 +19,25 @@ celix_subproject(RSA_DISCOVERY_SHM "Option to enable building the Discovery (SHM
 if (RSA_DISCOVERY_SHM)
 find_package(CURL REQUIRED)
 	find_package(LibXml2 REQUIRED)
-	
-	include_directories("${CURL_INCLUDE_DIR}")
-	include_directories("${LIBXML2_INCLUDE_DIR}")
-	include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery/private/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery_shm/private/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-	include_directories("private/include")
 
 	add_bundle(discovery_shm 
         VERSION 0.0.1
         SYMBOLIC_NAME "apache_celix_rsa_discovery_shm"
         NAME "Apache Celix RSA Discovery SHM"
         SOURCES
-		private/src/discovery_shm
-		private/src/discovery_shmWatcher
-		private/src/discovery_impl
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery_activator.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_reader.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_writer.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_poller.c
-		${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_server.c
-	    ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
-	    ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
-	    ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+			src/discovery_shm.c
+			src/discovery_shmWatcher.c
+			src/discovery_impl.c
 	)
+	target_include_directories(discovery_shm PRIVATE
+			src
+			${LIBXML2_INCLUDE_DIR}
+			${CURL_INCLUDE_DIR}
+	)
+	target_link_libraries(discovery_shm PRIVATE Celix::framework ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} discovery_common)
 
 	install_bundle(discovery_shm)
 		
-	target_link_libraries(discovery_shm celix_framework ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES})
+
 
 endif (RSA_DISCOVERY_SHM)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/include/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/include/discovery_impl.h b/remote_services/discovery_shm/private/include/discovery_impl.h
deleted file mode 100644
index c7206bd..0000000
--- a/remote_services/discovery_shm/private/include/discovery_impl.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * discovery_impl.h
- *
- *  \date       Oct 01, 2014
- *  \author    	<a href="mailto:celix-dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef DISCOVERY_IMPL_H_
-#define DISCOVERY_IMPL_H_
-
-#include "bundle_context.h"
-#include "service_reference.h"
-
-#include "endpoint_description.h"
-#include "endpoint_listener.h"
-
-#include "endpoint_discovery_poller.h"
-#include "endpoint_discovery_server.h"
-#include "discovery_shmWatcher.h"
-
-
-#define DEFAULT_SERVER_IP   "127.0.0.1"
-#define DEFAULT_SERVER_PORT "9999"
-#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.shm"
-#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.shm"
-
-#define MAX_ROOTNODE_LENGTH		 64
-#define MAX_LOCALNODE_LENGTH	256
-
-
-struct discovery {
-	bundle_context_pt context;
-
-	celix_thread_mutex_t listenerReferencesMutex;
-	celix_thread_mutex_t discoveredServicesMutex;
-
-	hash_map_pt listenerReferences; //key=serviceReference, value=nop
-	hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
-
-	shm_watcher_pt watcher;
-	endpoint_discovery_poller_pt poller;
-	endpoint_discovery_server_pt server;
-
-	log_helper_pt loghelper;
-};
-
-#endif /* DISCOVERY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/include/discovery_shm.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/include/discovery_shm.h b/remote_services/discovery_shm/private/include/discovery_shm.h
deleted file mode 100644
index 9c4593b..0000000
--- a/remote_services/discovery_shm/private/include/discovery_shm.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0 
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * shm.h
- *
- *  \date       26 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-
-
-#ifndef _DISCOVERY_SHM_H_
-#define _DISCOVERY_SHM_H_
-
-#include <celix_errno.h>
-
-#define SHM_ENTRY_MAX_KEY_LENGTH	256
-#define SHM_ENTRY_MAX_VALUE_LENGTH	256
-
-// defines the time-to-live in seconds
-#define SHM_ENTRY_DEFAULT_TTL		60
-
-// we currently support 64 separate discovery instances
-#define SHM_DATA_MAX_ENTRIES		64
-
-typedef struct shmData* shmData_pt;
-
-/* creates a new shared memory block */
-celix_status_t discoveryShm_create(shmData_pt* data);
-celix_status_t discoveryShm_attach(shmData_pt* data);
-celix_status_t discoveryShm_set(shmData_pt data, char *key, char* value);
-celix_status_t discoveryShm_get(shmData_pt data, char* key, char* value);
-celix_status_t discoveryShm_getKeys(shmData_pt data, char** keys, int* size);
-celix_status_t discoveryShm_remove(shmData_pt data, char* key);
-celix_status_t discoveryShm_detach(shmData_pt data);
-celix_status_t discoveryShm_destroy(shmData_pt data);
-
-#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/include/discovery_shmWatcher.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/include/discovery_shmWatcher.h b/remote_services/discovery_shm/private/include/discovery_shmWatcher.h
deleted file mode 100644
index ff70f72..0000000
--- a/remote_services/discovery_shm/private/include/discovery_shmWatcher.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * shm_watcher.h
- *
- * \date       30 Sep 2014
- * \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright  Apache License, Version 2.0
- */
-
-#ifndef DISCOVERY_SHM_WATCHER_H_
-#define DISCOVERY_SHM_WATCHER_H_
-
-#include "celix_errno.h"
-#include "discovery.h"
-#include "endpoint_discovery_poller.h"
-
-typedef struct shm_watcher *shm_watcher_pt;
-
-celix_status_t discoveryShmWatcher_create(discovery_pt discovery);
-celix_status_t discoveryShmWatcher_destroy(discovery_pt discovery);
-
-
-#endif /* DISCOVERY_SHM_WATCHER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/src/discovery_impl.c b/remote_services/discovery_shm/private/src/discovery_impl.c
deleted file mode 100644
index 2604595..0000000
--- a/remote_services/discovery_shm/private/src/discovery_impl.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery_impl.c
- *
- * \date        Aug 8, 2014
- * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright	Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <netdb.h>
-#include <netinet/in.h>
-
-#include "constants.h"
-#include "celix_threads.h"
-#include "bundle_context.h"
-#include "array_list.h"
-#include "utils.h"
-#include "celix_errno.h"
-#include "filter.h"
-#include "service_reference.h"
-#include "service_registration.h"
-#include "remote_constants.h"
-
-
-#include "discovery.h"
-#include "discovery_impl.h"
-#include "discovery_shmWatcher.h"
-#include "endpoint_discovery_poller.h"
-#include "endpoint_discovery_server.h"
-
-
-
-celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*discovery = calloc(1, sizeof(struct discovery));
-	if (!*discovery) {
-		status = CELIX_ENOMEM;
-	} else {
-        (*discovery)->context = context;
-        (*discovery)->poller = NULL;
-        (*discovery)->server = NULL;
-
-        (*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
-        (*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-        celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
-        celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
-
-        if (logHelper_create(context, &(*discovery)->loghelper) == CELIX_SUCCESS) {
-            logHelper_start((*discovery)->loghelper);
-        }
-    }
-
-	return status;
-}
-
-
-
-celix_status_t discovery_destroy(discovery_pt discovery) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	discovery->context = NULL;
-	discovery->poller = NULL;
-	discovery->server = NULL;
-
-	celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
-	hashMap_destroy(discovery->discoveredServices, false, false);
-	discovery->discoveredServices = NULL;
-
-	celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
-	celixThreadMutex_destroy(&discovery->discoveredServicesMutex);
-
-	celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
-	hashMap_destroy(discovery->listenerReferences, false, false);
-	discovery->listenerReferences = NULL;
-
-	celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
-
-	celixThreadMutex_destroy(&discovery->listenerReferencesMutex);
-
-
-
-
-	free(discovery);
-
-	return status;
-}
-
-celix_status_t discovery_start(discovery_pt discovery) {
-    celix_status_t status;
-
-    status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
-    if (status == CELIX_SUCCESS) {
-        status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
-    }
-
-    if (status == CELIX_SUCCESS) {
-        status = discoveryShmWatcher_create(discovery);
-    }
-
-    return status;
-}
-
-celix_status_t discovery_stop(discovery_pt discovery) {
-	celix_status_t status;
-
-    status = discoveryShmWatcher_destroy(discovery);
-
-    if (status == CELIX_SUCCESS) {
-        status = endpointDiscoveryServer_destroy(discovery->server);
-    }
-
-	endpointDiscoveryPoller_destroy(discovery->poller);
-
-	if (status == CELIX_SUCCESS) {
-        hash_map_iterator_pt iter;
-
-        celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
-        iter = hashMapIterator_create(discovery->discoveredServices);
-        while (hashMapIterator_hasNext(iter)) {
-            hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-            endpoint_description_pt endpoint = hashMapEntry_getValue(entry);
-
-            discovery_informEndpointListeners(discovery, endpoint, false);
-        }
-        hashMapIterator_destroy(iter);
-
-        celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
-        logHelper_stop(discovery->loghelper);
-        logHelper_destroy(&discovery->loghelper);
-	}
-
-	return status;
-}
-
-
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/src/discovery_shm.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/src/discovery_shm.c b/remote_services/discovery_shm/private/src/discovery_shm.c
deleted file mode 100644
index 1b1170e..0000000
--- a/remote_services/discovery_shm/private/src/discovery_shm.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0 
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * discovery_shm.c
- *
- *  \date       26 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-
-
-#include <stdio.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <sys/types.h>
-#include <sys/sem.h>
-#include <sys/shm.h>
-
-#include <celix_errno.h>
-#include <celix_threads.h>
-
-#include "discovery_shm.h"
-
-#define DISCOVERY_SHM_MEMSIZE 262144
-#define DISCOVERY_SHM_FILENAME "/dev/null"
-#define DISCOVERY_SHM_FTOK_ID 50
-#define DISCOVERY_SEM_FILENAME "/dev/null"
-#define DISCOVERY_SEM_FTOK_ID 54
-
-struct shmEntry {
-    char key[SHM_ENTRY_MAX_KEY_LENGTH];
-    char value[SHM_ENTRY_MAX_VALUE_LENGTH];
-
-    time_t expires;
-};
-
-typedef struct shmEntry shmEntry;
-
-struct shmData {
-    shmEntry entries[SHM_DATA_MAX_ENTRIES];
-    int numOfEntries;
-    int shmId;
-
-    celix_thread_mutex_t globalLock;
-};
-
-void* shmAdress;
-
-static celix_status_t discoveryShm_removeWithIndex(shmData_pt data, int index);
-
-/* returns the ftok key to identify shared memory*/
-static key_t discoveryShm_getKey() {
-    return ftok(DISCOVERY_SHM_FILENAME, DISCOVERY_SHM_FTOK_ID);
-}
-
-/* creates a new shared memory block */
-celix_status_t discoveryShm_create(shmData_pt* data) {
-    celix_status_t status;
-
-    shmData_pt shmData = calloc(1, sizeof(*shmData));
-    key_t shmKey = discoveryShm_getKey();
-
-    if (!shmData) {
-        status = CELIX_ENOMEM;
-    } else if ((shmData->shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, IPC_CREAT | 0666)) < 0) {
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else if ((shmAdress = shmat(shmData->shmId, 0, 0)) == (char*) -1) {
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        celix_thread_mutexattr_t threadAttr;
-
-        shmData->numOfEntries = 0;
-
-        status = celixThreadMutexAttr_create(&threadAttr);
-
-#ifdef LINUX
-        if (status == CELIX_SUCCESS) {
-            // This is Linux specific
-            status = pthread_mutexattr_setrobust(&threadAttr, PTHREAD_MUTEX_ROBUST);
-        }
-#endif
-
-        if (status == CELIX_SUCCESS) {
-            status = celixThreadMutex_create(&shmData->globalLock, &threadAttr);
-        }
-
-        if (status == CELIX_SUCCESS) {
-            memcpy(shmAdress, shmData, sizeof(struct shmData));
-            (*data) = shmAdress;
-        }
-    }
-
-    free(shmData);
-
-    return status;
-}
-
-celix_status_t discoveryShm_attach(shmData_pt* data) {
-    celix_status_t status = CELIX_SUCCESS;
-    key_t shmKey = ftok(DISCOVERY_SHM_FILENAME, DISCOVERY_SHM_FTOK_ID);
-    int shmId = -1;
-
-    if ((shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, 0666)) < 0) {
-        status = CELIX_BUNDLE_EXCEPTION;
-    }
-
-    /* shmat has a curious return value of (void*)-1 in case of error */
-    void *mem=shmat(shmId, 0, 0);
-    if(mem==((void*)-1)){
-	status = CELIX_BUNDLE_EXCEPTION;
-    }
-    else{
-	(*data)=mem;
-    }
-
-    return status;
-}
-
-static celix_status_t discoveryShm_getwithIndex(shmData_pt data, char* key, char* value, int* index) {
-    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-    time_t currentTime = time(NULL);
-    unsigned int i;
-
-    for (i = 0; i < data->numOfEntries && status != CELIX_SUCCESS; i++) {
-        shmEntry entry = data->entries[i];
-        // check if entry is still valid
-        if (data->entries[i].expires < currentTime) {
-            discoveryShm_removeWithIndex(data, i);
-        } else if (strcmp(entry.key, key) == 0) {
-            if (value) {
-                strcpy(value, entry.value);
-            }
-            if (index) {
-                (*index) = i;
-            }
-            status = CELIX_SUCCESS;
-        }
-    }
-
-    return status;
-}
-
-celix_status_t discoveryShm_getKeys(shmData_pt data, char** keys, int* size) {
-    celix_status_t status;
-
-    status = celixThreadMutex_lock(&data->globalLock);
-
-    if (status == CELIX_SUCCESS) {
-    	unsigned int i = 0;
-        for (i = 0; i < data->numOfEntries; i++) {
-            shmEntry entry = data->entries[i];
-
-            if (strlen(entry.key)>0) {
-                snprintf(keys[i], SHM_ENTRY_MAX_KEY_LENGTH, "%s", entry.key);
-            }
-        }
-
-        (*size) = i;
-
-        celixThreadMutex_unlock(&data->globalLock);
-    }
-
-    return status;
-}
-
-celix_status_t discoveryShm_set(shmData_pt data, char *key, char* value) {
-    celix_status_t status;
-    int index = -1;
-
-    if (data->numOfEntries >= SHM_DATA_MAX_ENTRIES) {
-        status = CELIX_ILLEGAL_STATE;
-    } else {
-        status = celixThreadMutex_lock(&data->globalLock);
-
-        if (status == CELIX_SUCCESS) {
-            // check if key already there
-            status = discoveryShm_getwithIndex(data, key, NULL, &index);
-            if (status != CELIX_SUCCESS) {
-                index = data->numOfEntries;
-
-                snprintf(data->entries[index].key, SHM_ENTRY_MAX_KEY_LENGTH, "%s", key);
-                data->numOfEntries++;
-
-                 status = CELIX_SUCCESS;
-            }
-
-            snprintf(data->entries[index].value, SHM_ENTRY_MAX_VALUE_LENGTH, "%s", value);
-            data->entries[index].expires = (time(NULL) + SHM_ENTRY_DEFAULT_TTL);
-
-            celixThreadMutex_unlock(&data->globalLock);
-        }
-    }
-
-    return status;
-}
-
-celix_status_t discoveryShm_get(shmData_pt data, char* key, char* value) {
-    celix_status_t status;
-
-    status = celixThreadMutex_lock(&data->globalLock);
-
-    if (status == CELIX_SUCCESS) {
-        status = discoveryShm_getwithIndex(data, key, value, NULL);
-
-        celixThreadMutex_unlock(&data->globalLock);
-    }
-
-    return status;
-}
-
-static celix_status_t discoveryShm_removeWithIndex(shmData_pt data, int index) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    data->numOfEntries--;
-    if (index < data->numOfEntries) {
-        memcpy((void*) &data->entries[index], (void*) &data->entries[index + 1], ((data->numOfEntries - index) * sizeof(struct shmEntry)));
-    }
-
-    return status;
-}
-
-celix_status_t discoveryShm_remove(shmData_pt data, char* key) {
-    celix_status_t status;
-    int index = -1;
-
-    status = celixThreadMutex_lock(&data->globalLock);
-
-    if (status == CELIX_SUCCESS) {
-        status = discoveryShm_getwithIndex(data, key, NULL, &index);
-
-        if (status == CELIX_SUCCESS) {
-            status = discoveryShm_removeWithIndex(data, index);
-        }
-
-        celixThreadMutex_unlock(&data->globalLock);
-    }
-
-    return status;
-}
-
-celix_status_t discoveryShm_detach(shmData_pt data) {
-    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
-    if (data->numOfEntries == 0) {
-        status = discoveryShm_destroy(data);
-    }
-    else if (shmdt(shmAdress) == 0) {
-        status = CELIX_SUCCESS;
-    }
-
-    return status;
-}
-
-celix_status_t discoveryShm_destroy(shmData_pt data) {
-    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
-    if (shmctl(data->shmId, IPC_RMID, 0) == 0) {
-        status = CELIX_SUCCESS;
-    }
-
-    return status;
-
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/src/discovery_shmWatcher.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/src/discovery_shmWatcher.c b/remote_services/discovery_shm/private/src/discovery_shmWatcher.c
deleted file mode 100644
index 6460de8..0000000
--- a/remote_services/discovery_shm/private/src/discovery_shmWatcher.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery_shmWatcher.c
- *
- * \date       16 Sep 2014
- * \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright  Apache License, Version 2.0
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-
-#include "celix_log.h"
-#include "constants.h"
-#include "discovery_impl.h"
-
-#include "discovery_shm.h"
-#include "discovery_shmWatcher.h"
-
-#include "endpoint_discovery_poller.h"
-
-struct shm_watcher {
-    shmData_pt shmData;
-    celix_thread_t watcherThread;
-    celix_thread_mutex_t watcherLock;
-
-    volatile bool running;
-};
-
-// note that the rootNode shouldn't have a leading slash
-static celix_status_t discoveryShmWatcher_getRootPath(char* rootNode) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    strcpy(rootNode, "discovery");
-
-    return status;
-}
-
-static celix_status_t discoveryShmWatcher_getLocalNodePath(bundle_context_pt context, char* localNodePath) {
-    celix_status_t status;
-    char rootPath[MAX_ROOTNODE_LENGTH];
-    const char* uuid = NULL;
-
-    status = discoveryShmWatcher_getRootPath(&rootPath[0]);
-
-    if (status == CELIX_SUCCESS) {
-        status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-    }
-
-    if (status == CELIX_SUCCESS) {
-        if (rootPath[strlen(&rootPath[0]) - 1] == '/') {
-            snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s%s", &rootPath[0], uuid);
-        } else {
-            snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s/%s", &rootPath[0], uuid);
-        }
-    }
-
-    return status;
-}
-
-/* retrieves all endpoints from shm and syncs them with the ones already available */
-static celix_status_t discoveryShmWatcher_syncEndpoints(discovery_pt discovery) {
-    celix_status_t status = CELIX_SUCCESS;
-    shm_watcher_pt watcher = discovery->watcher;
-    char** shmKeyArr = calloc(SHM_DATA_MAX_ENTRIES, sizeof(*shmKeyArr));
-    array_list_pt registeredKeyArr = NULL;
-
-    int i, j, shmSize;
-
-    for (i = 0; i < SHM_DATA_MAX_ENTRIES; i++) {
-        shmKeyArr[i] = calloc(SHM_ENTRY_MAX_KEY_LENGTH, sizeof(*shmKeyArr[i]));
-    }
-
-    arrayList_create(&registeredKeyArr);
-
-    // get all urls available in shm
-    discoveryShm_getKeys(watcher->shmData, shmKeyArr, &shmSize);
-
-    // get all locally registered endpoints
-    endpointDiscoveryPoller_getDiscoveryEndpoints(discovery->poller, registeredKeyArr);
-
-    // add discovery points which are in shm, but not local yet
-    for (i = 0; i < shmSize; i++) {
-        char url[SHM_ENTRY_MAX_VALUE_LENGTH];
-
-        if (discoveryShm_get(watcher->shmData, shmKeyArr[i], &url[0]) == CELIX_SUCCESS) {
-            bool elementFound = false;
-
-            for (j = 0; j < arrayList_size(registeredKeyArr) && elementFound == false; j++) {
-
-                if (strcmp(url, (char*) arrayList_get(registeredKeyArr, j)) == 0) {
-                    free(arrayList_remove(registeredKeyArr, j));
-                    elementFound = true;
-                }
-            }
-
-            if (elementFound == false) {
-                endpointDiscoveryPoller_addDiscoveryEndpoint(discovery->poller, url);
-            }
-        }
-    }
-
-    // remove those which are not in shm
-    for (i = 0; i < arrayList_size(registeredKeyArr); i++) {
-        char* regUrl = arrayList_get(registeredKeyArr, i);
-
-        if (regUrl != NULL) {
-            endpointDiscoveryPoller_removeDiscoveryEndpoint(discovery->poller, regUrl);
-        }
-    }
-
-    for (i = 0; i < SHM_DATA_MAX_ENTRIES; i++) {
-        free(shmKeyArr[i]);
-    }
-
-    free(shmKeyArr);
-
-    for (j = 0; j < arrayList_size(registeredKeyArr); j++) {
-        free(arrayList_get(registeredKeyArr, j));
-    }
-
-    arrayList_destroy(registeredKeyArr);
-
-    return status;
-}
-
-static void* discoveryShmWatcher_run(void* data) {
-    discovery_pt discovery = (discovery_pt) data;
-    shm_watcher_pt watcher = discovery->watcher;
-    char localNodePath[MAX_LOCALNODE_LENGTH];
-    char url[MAX_LOCALNODE_LENGTH];
-
-    if (discoveryShmWatcher_getLocalNodePath(discovery->context, &localNodePath[0]) != CELIX_SUCCESS) {
-        logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot retrieve local discovery path.");
-    }
-
-    if (endpointDiscoveryServer_getUrl(discovery->server, &url[0]) != CELIX_SUCCESS) {
-        snprintf(url, MAX_LOCALNODE_LENGTH, "http://%s:%s/%s", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT, DEFAULT_SERVER_PATH);
-    }
-
-    while (watcher->running) {
-        // register own framework
-        if (discoveryShm_set(watcher->shmData, localNodePath, url) != CELIX_SUCCESS) {
-            logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot set local discovery registration.");
-        }
-
-        discoveryShmWatcher_syncEndpoints(discovery);
-        sleep(5);
-    }
-
-    return NULL;
-}
-
-celix_status_t discoveryShmWatcher_create(discovery_pt discovery) {
-    celix_status_t status = CELIX_SUCCESS;
-    shm_watcher_pt watcher = NULL;
-
-    watcher = calloc(1, sizeof(*watcher));
-
-    if (!watcher) {
-        status = CELIX_ENOMEM;
-    } else {
-        status = discoveryShm_attach(&(watcher->shmData));
-
-        if (status != CELIX_SUCCESS) {
-            logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_DEBUG, "Attaching to Shared Memory Failed. Trying to create.");
-
-            status = discoveryShm_create(&(watcher->shmData));
-
-            if (status != CELIX_SUCCESS) {
-                logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_ERROR, "Failed to create Shared Memory Segment.");
-            }
-        }
-
-        if (status == CELIX_SUCCESS) {
-            discovery->watcher = watcher;
-        }
-        else{
-        	discovery->watcher = NULL;
-        	free(watcher);
-        }
-
-    }
-
-    if (status == CELIX_SUCCESS) {
-        status += celixThreadMutex_create(&watcher->watcherLock, NULL);
-        status += celixThreadMutex_lock(&watcher->watcherLock);
-        watcher->running = true;
-        status += celixThread_create(&watcher->watcherThread, NULL, discoveryShmWatcher_run, discovery);
-        status += celixThreadMutex_unlock(&watcher->watcherLock);
-    }
-
-    return status;
-}
-
-celix_status_t discoveryShmWatcher_destroy(discovery_pt discovery) {
-    celix_status_t status;
-    shm_watcher_pt watcher = discovery->watcher;
-    char localNodePath[MAX_LOCALNODE_LENGTH];
-
-    celixThreadMutex_lock(&watcher->watcherLock);
-    watcher->running = false;
-    celixThreadMutex_unlock(&watcher->watcherLock);
-
-    celixThread_join(watcher->watcherThread, NULL);
-
-    // remove own framework
-    status = discoveryShmWatcher_getLocalNodePath(discovery->context, &localNodePath[0]);
-
-    if (status == CELIX_SUCCESS) {
-        status = discoveryShm_remove(watcher->shmData, localNodePath);
-    }
-
-    if (status == CELIX_SUCCESS) {
-        discoveryShm_detach(watcher->shmData);
-        free(watcher);
-    }
-    else {
-        logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot remove local discovery registration.");
-    }
-
-
-    return status;
-}
-

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_impl.c b/remote_services/discovery_shm/src/discovery_impl.c
new file mode 100644
index 0000000..2604595
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_impl.c
@@ -0,0 +1,163 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery_impl.c
+ *
+ * \date        Aug 8, 2014
+ * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#include "constants.h"
+#include "celix_threads.h"
+#include "bundle_context.h"
+#include "array_list.h"
+#include "utils.h"
+#include "celix_errno.h"
+#include "filter.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "remote_constants.h"
+
+
+#include "discovery.h"
+#include "discovery_impl.h"
+#include "discovery_shmWatcher.h"
+#include "endpoint_discovery_poller.h"
+#include "endpoint_discovery_server.h"
+
+
+
+celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*discovery = calloc(1, sizeof(struct discovery));
+	if (!*discovery) {
+		status = CELIX_ENOMEM;
+	} else {
+        (*discovery)->context = context;
+        (*discovery)->poller = NULL;
+        (*discovery)->server = NULL;
+
+        (*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+        (*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+        celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
+        celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
+
+        if (logHelper_create(context, &(*discovery)->loghelper) == CELIX_SUCCESS) {
+            logHelper_start((*discovery)->loghelper);
+        }
+    }
+
+	return status;
+}
+
+
+
+celix_status_t discovery_destroy(discovery_pt discovery) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	discovery->context = NULL;
+	discovery->poller = NULL;
+	discovery->server = NULL;
+
+	celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+	hashMap_destroy(discovery->discoveredServices, false, false);
+	discovery->discoveredServices = NULL;
+
+	celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+	celixThreadMutex_destroy(&discovery->discoveredServicesMutex);
+
+	celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+	hashMap_destroy(discovery->listenerReferences, false, false);
+	discovery->listenerReferences = NULL;
+
+	celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+
+	celixThreadMutex_destroy(&discovery->listenerReferencesMutex);
+
+
+
+
+	free(discovery);
+
+	return status;
+}
+
+celix_status_t discovery_start(discovery_pt discovery) {
+    celix_status_t status;
+
+    status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
+    if (status == CELIX_SUCCESS) {
+        status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
+    }
+
+    if (status == CELIX_SUCCESS) {
+        status = discoveryShmWatcher_create(discovery);
+    }
+
+    return status;
+}
+
+celix_status_t discovery_stop(discovery_pt discovery) {
+	celix_status_t status;
+
+    status = discoveryShmWatcher_destroy(discovery);
+
+    if (status == CELIX_SUCCESS) {
+        status = endpointDiscoveryServer_destroy(discovery->server);
+    }
+
+	endpointDiscoveryPoller_destroy(discovery->poller);
+
+	if (status == CELIX_SUCCESS) {
+        hash_map_iterator_pt iter;
+
+        celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+        iter = hashMapIterator_create(discovery->discoveredServices);
+        while (hashMapIterator_hasNext(iter)) {
+            hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+            endpoint_description_pt endpoint = hashMapEntry_getValue(entry);
+
+            discovery_informEndpointListeners(discovery, endpoint, false);
+        }
+        hashMapIterator_destroy(iter);
+
+        celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+        logHelper_stop(discovery->loghelper);
+        logHelper_destroy(&discovery->loghelper);
+	}
+
+	return status;
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_impl.h b/remote_services/discovery_shm/src/discovery_impl.h
new file mode 100644
index 0000000..c7206bd
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_impl.h
@@ -0,0 +1,66 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * discovery_impl.h
+ *
+ *  \date       Oct 01, 2014
+ *  \author    	<a href="mailto:celix-dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef DISCOVERY_IMPL_H_
+#define DISCOVERY_IMPL_H_
+
+#include "bundle_context.h"
+#include "service_reference.h"
+
+#include "endpoint_description.h"
+#include "endpoint_listener.h"
+
+#include "endpoint_discovery_poller.h"
+#include "endpoint_discovery_server.h"
+#include "discovery_shmWatcher.h"
+
+
+#define DEFAULT_SERVER_IP   "127.0.0.1"
+#define DEFAULT_SERVER_PORT "9999"
+#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.shm"
+#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.shm"
+
+#define MAX_ROOTNODE_LENGTH		 64
+#define MAX_LOCALNODE_LENGTH	256
+
+
+struct discovery {
+	bundle_context_pt context;
+
+	celix_thread_mutex_t listenerReferencesMutex;
+	celix_thread_mutex_t discoveredServicesMutex;
+
+	hash_map_pt listenerReferences; //key=serviceReference, value=nop
+	hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
+
+	shm_watcher_pt watcher;
+	endpoint_discovery_poller_pt poller;
+	endpoint_discovery_server_pt server;
+
+	log_helper_pt loghelper;
+};
+
+#endif /* DISCOVERY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_shm.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shm.c b/remote_services/discovery_shm/src/discovery_shm.c
new file mode 100644
index 0000000..1b1170e
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_shm.c
@@ -0,0 +1,284 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * discovery_shm.c
+ *
+ *  \date       26 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+
+
+#include <stdio.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <sys/types.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+
+#include <celix_errno.h>
+#include <celix_threads.h>
+
+#include "discovery_shm.h"
+
+#define DISCOVERY_SHM_MEMSIZE 262144
+#define DISCOVERY_SHM_FILENAME "/dev/null"
+#define DISCOVERY_SHM_FTOK_ID 50
+#define DISCOVERY_SEM_FILENAME "/dev/null"
+#define DISCOVERY_SEM_FTOK_ID 54
+
+struct shmEntry {
+    char key[SHM_ENTRY_MAX_KEY_LENGTH];
+    char value[SHM_ENTRY_MAX_VALUE_LENGTH];
+
+    time_t expires;
+};
+
+typedef struct shmEntry shmEntry;
+
+struct shmData {
+    shmEntry entries[SHM_DATA_MAX_ENTRIES];
+    int numOfEntries;
+    int shmId;
+
+    celix_thread_mutex_t globalLock;
+};
+
+void* shmAdress;
+
+static celix_status_t discoveryShm_removeWithIndex(shmData_pt data, int index);
+
+/* returns the ftok key to identify shared memory*/
+static key_t discoveryShm_getKey() {
+    return ftok(DISCOVERY_SHM_FILENAME, DISCOVERY_SHM_FTOK_ID);
+}
+
+/* creates a new shared memory block */
+celix_status_t discoveryShm_create(shmData_pt* data) {
+    celix_status_t status;
+
+    shmData_pt shmData = calloc(1, sizeof(*shmData));
+    key_t shmKey = discoveryShm_getKey();
+
+    if (!shmData) {
+        status = CELIX_ENOMEM;
+    } else if ((shmData->shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, IPC_CREAT | 0666)) < 0) {
+        status = CELIX_BUNDLE_EXCEPTION;
+    } else if ((shmAdress = shmat(shmData->shmId, 0, 0)) == (char*) -1) {
+        status = CELIX_BUNDLE_EXCEPTION;
+    } else {
+        celix_thread_mutexattr_t threadAttr;
+
+        shmData->numOfEntries = 0;
+
+        status = celixThreadMutexAttr_create(&threadAttr);
+
+#ifdef LINUX
+        if (status == CELIX_SUCCESS) {
+            // This is Linux specific
+            status = pthread_mutexattr_setrobust(&threadAttr, PTHREAD_MUTEX_ROBUST);
+        }
+#endif
+
+        if (status == CELIX_SUCCESS) {
+            status = celixThreadMutex_create(&shmData->globalLock, &threadAttr);
+        }
+
+        if (status == CELIX_SUCCESS) {
+            memcpy(shmAdress, shmData, sizeof(struct shmData));
+            (*data) = shmAdress;
+        }
+    }
+
+    free(shmData);
+
+    return status;
+}
+
+celix_status_t discoveryShm_attach(shmData_pt* data) {
+    celix_status_t status = CELIX_SUCCESS;
+    key_t shmKey = ftok(DISCOVERY_SHM_FILENAME, DISCOVERY_SHM_FTOK_ID);
+    int shmId = -1;
+
+    if ((shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, 0666)) < 0) {
+        status = CELIX_BUNDLE_EXCEPTION;
+    }
+
+    /* shmat has a curious return value of (void*)-1 in case of error */
+    void *mem=shmat(shmId, 0, 0);
+    if(mem==((void*)-1)){
+	status = CELIX_BUNDLE_EXCEPTION;
+    }
+    else{
+	(*data)=mem;
+    }
+
+    return status;
+}
+
+static celix_status_t discoveryShm_getwithIndex(shmData_pt data, char* key, char* value, int* index) {
+    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+    time_t currentTime = time(NULL);
+    unsigned int i;
+
+    for (i = 0; i < data->numOfEntries && status != CELIX_SUCCESS; i++) {
+        shmEntry entry = data->entries[i];
+        // check if entry is still valid
+        if (data->entries[i].expires < currentTime) {
+            discoveryShm_removeWithIndex(data, i);
+        } else if (strcmp(entry.key, key) == 0) {
+            if (value) {
+                strcpy(value, entry.value);
+            }
+            if (index) {
+                (*index) = i;
+            }
+            status = CELIX_SUCCESS;
+        }
+    }
+
+    return status;
+}
+
+celix_status_t discoveryShm_getKeys(shmData_pt data, char** keys, int* size) {
+    celix_status_t status;
+
+    status = celixThreadMutex_lock(&data->globalLock);
+
+    if (status == CELIX_SUCCESS) {
+    	unsigned int i = 0;
+        for (i = 0; i < data->numOfEntries; i++) {
+            shmEntry entry = data->entries[i];
+
+            if (strlen(entry.key)>0) {
+                snprintf(keys[i], SHM_ENTRY_MAX_KEY_LENGTH, "%s", entry.key);
+            }
+        }
+
+        (*size) = i;
+
+        celixThreadMutex_unlock(&data->globalLock);
+    }
+
+    return status;
+}
+
+celix_status_t discoveryShm_set(shmData_pt data, char *key, char* value) {
+    celix_status_t status;
+    int index = -1;
+
+    if (data->numOfEntries >= SHM_DATA_MAX_ENTRIES) {
+        status = CELIX_ILLEGAL_STATE;
+    } else {
+        status = celixThreadMutex_lock(&data->globalLock);
+
+        if (status == CELIX_SUCCESS) {
+            // check if key already there
+            status = discoveryShm_getwithIndex(data, key, NULL, &index);
+            if (status != CELIX_SUCCESS) {
+                index = data->numOfEntries;
+
+                snprintf(data->entries[index].key, SHM_ENTRY_MAX_KEY_LENGTH, "%s", key);
+                data->numOfEntries++;
+
+                 status = CELIX_SUCCESS;
+            }
+
+            snprintf(data->entries[index].value, SHM_ENTRY_MAX_VALUE_LENGTH, "%s", value);
+            data->entries[index].expires = (time(NULL) + SHM_ENTRY_DEFAULT_TTL);
+
+            celixThreadMutex_unlock(&data->globalLock);
+        }
+    }
+
+    return status;
+}
+
+celix_status_t discoveryShm_get(shmData_pt data, char* key, char* value) {
+    celix_status_t status;
+
+    status = celixThreadMutex_lock(&data->globalLock);
+
+    if (status == CELIX_SUCCESS) {
+        status = discoveryShm_getwithIndex(data, key, value, NULL);
+
+        celixThreadMutex_unlock(&data->globalLock);
+    }
+
+    return status;
+}
+
+static celix_status_t discoveryShm_removeWithIndex(shmData_pt data, int index) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    data->numOfEntries--;
+    if (index < data->numOfEntries) {
+        memcpy((void*) &data->entries[index], (void*) &data->entries[index + 1], ((data->numOfEntries - index) * sizeof(struct shmEntry)));
+    }
+
+    return status;
+}
+
+celix_status_t discoveryShm_remove(shmData_pt data, char* key) {
+    celix_status_t status;
+    int index = -1;
+
+    status = celixThreadMutex_lock(&data->globalLock);
+
+    if (status == CELIX_SUCCESS) {
+        status = discoveryShm_getwithIndex(data, key, NULL, &index);
+
+        if (status == CELIX_SUCCESS) {
+            status = discoveryShm_removeWithIndex(data, index);
+        }
+
+        celixThreadMutex_unlock(&data->globalLock);
+    }
+
+    return status;
+}
+
+celix_status_t discoveryShm_detach(shmData_pt data) {
+    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+    if (data->numOfEntries == 0) {
+        status = discoveryShm_destroy(data);
+    }
+    else if (shmdt(shmAdress) == 0) {
+        status = CELIX_SUCCESS;
+    }
+
+    return status;
+}
+
+celix_status_t discoveryShm_destroy(shmData_pt data) {
+    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+    if (shmctl(data->shmId, IPC_RMID, 0) == 0) {
+        status = CELIX_SUCCESS;
+    }
+
+    return status;
+
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_shm.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shm.h b/remote_services/discovery_shm/src/discovery_shm.h
new file mode 100644
index 0000000..9c4593b
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_shm.h
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * shm.h
+ *
+ *  \date       26 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+
+
+#ifndef _DISCOVERY_SHM_H_
+#define _DISCOVERY_SHM_H_
+
+#include <celix_errno.h>
+
+#define SHM_ENTRY_MAX_KEY_LENGTH	256
+#define SHM_ENTRY_MAX_VALUE_LENGTH	256
+
+// defines the time-to-live in seconds
+#define SHM_ENTRY_DEFAULT_TTL		60
+
+// we currently support 64 separate discovery instances
+#define SHM_DATA_MAX_ENTRIES		64
+
+typedef struct shmData* shmData_pt;
+
+/* creates a new shared memory block */
+celix_status_t discoveryShm_create(shmData_pt* data);
+celix_status_t discoveryShm_attach(shmData_pt* data);
+celix_status_t discoveryShm_set(shmData_pt data, char *key, char* value);
+celix_status_t discoveryShm_get(shmData_pt data, char* key, char* value);
+celix_status_t discoveryShm_getKeys(shmData_pt data, char** keys, int* size);
+celix_status_t discoveryShm_remove(shmData_pt data, char* key);
+celix_status_t discoveryShm_detach(shmData_pt data);
+celix_status_t discoveryShm_destroy(shmData_pt data);
+
+#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_shmWatcher.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shmWatcher.c b/remote_services/discovery_shm/src/discovery_shmWatcher.c
new file mode 100644
index 0000000..6460de8
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_shmWatcher.c
@@ -0,0 +1,246 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery_shmWatcher.c
+ *
+ * \date       16 Sep 2014
+ * \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright  Apache License, Version 2.0
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+
+#include "celix_log.h"
+#include "constants.h"
+#include "discovery_impl.h"
+
+#include "discovery_shm.h"
+#include "discovery_shmWatcher.h"
+
+#include "endpoint_discovery_poller.h"
+
+struct shm_watcher {
+    shmData_pt shmData;
+    celix_thread_t watcherThread;
+    celix_thread_mutex_t watcherLock;
+
+    volatile bool running;
+};
+
+// note that the rootNode shouldn't have a leading slash
+static celix_status_t discoveryShmWatcher_getRootPath(char* rootNode) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    strcpy(rootNode, "discovery");
+
+    return status;
+}
+
+static celix_status_t discoveryShmWatcher_getLocalNodePath(bundle_context_pt context, char* localNodePath) {
+    celix_status_t status;
+    char rootPath[MAX_ROOTNODE_LENGTH];
+    const char* uuid = NULL;
+
+    status = discoveryShmWatcher_getRootPath(&rootPath[0]);
+
+    if (status == CELIX_SUCCESS) {
+        status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+    }
+
+    if (status == CELIX_SUCCESS) {
+        if (rootPath[strlen(&rootPath[0]) - 1] == '/') {
+            snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s%s", &rootPath[0], uuid);
+        } else {
+            snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s/%s", &rootPath[0], uuid);
+        }
+    }
+
+    return status;
+}
+
+/* retrieves all endpoints from shm and syncs them with the ones already available */
+static celix_status_t discoveryShmWatcher_syncEndpoints(discovery_pt discovery) {
+    celix_status_t status = CELIX_SUCCESS;
+    shm_watcher_pt watcher = discovery->watcher;
+    char** shmKeyArr = calloc(SHM_DATA_MAX_ENTRIES, sizeof(*shmKeyArr));
+    array_list_pt registeredKeyArr = NULL;
+
+    int i, j, shmSize;
+
+    for (i = 0; i < SHM_DATA_MAX_ENTRIES; i++) {
+        shmKeyArr[i] = calloc(SHM_ENTRY_MAX_KEY_LENGTH, sizeof(*shmKeyArr[i]));
+    }
+
+    arrayList_create(&registeredKeyArr);
+
+    // get all urls available in shm
+    discoveryShm_getKeys(watcher->shmData, shmKeyArr, &shmSize);
+
+    // get all locally registered endpoints
+    endpointDiscoveryPoller_getDiscoveryEndpoints(discovery->poller, registeredKeyArr);
+
+    // add discovery points which are in shm, but not local yet
+    for (i = 0; i < shmSize; i++) {
+        char url[SHM_ENTRY_MAX_VALUE_LENGTH];
+
+        if (discoveryShm_get(watcher->shmData, shmKeyArr[i], &url[0]) == CELIX_SUCCESS) {
+            bool elementFound = false;
+
+            for (j = 0; j < arrayList_size(registeredKeyArr) && elementFound == false; j++) {
+
+                if (strcmp(url, (char*) arrayList_get(registeredKeyArr, j)) == 0) {
+                    free(arrayList_remove(registeredKeyArr, j));
+                    elementFound = true;
+                }
+            }
+
+            if (elementFound == false) {
+                endpointDiscoveryPoller_addDiscoveryEndpoint(discovery->poller, url);
+            }
+        }
+    }
+
+    // remove those which are not in shm
+    for (i = 0; i < arrayList_size(registeredKeyArr); i++) {
+        char* regUrl = arrayList_get(registeredKeyArr, i);
+
+        if (regUrl != NULL) {
+            endpointDiscoveryPoller_removeDiscoveryEndpoint(discovery->poller, regUrl);
+        }
+    }
+
+    for (i = 0; i < SHM_DATA_MAX_ENTRIES; i++) {
+        free(shmKeyArr[i]);
+    }
+
+    free(shmKeyArr);
+
+    for (j = 0; j < arrayList_size(registeredKeyArr); j++) {
+        free(arrayList_get(registeredKeyArr, j));
+    }
+
+    arrayList_destroy(registeredKeyArr);
+
+    return status;
+}
+
+static void* discoveryShmWatcher_run(void* data) {
+    discovery_pt discovery = (discovery_pt) data;
+    shm_watcher_pt watcher = discovery->watcher;
+    char localNodePath[MAX_LOCALNODE_LENGTH];
+    char url[MAX_LOCALNODE_LENGTH];
+
+    if (discoveryShmWatcher_getLocalNodePath(discovery->context, &localNodePath[0]) != CELIX_SUCCESS) {
+        logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot retrieve local discovery path.");
+    }
+
+    if (endpointDiscoveryServer_getUrl(discovery->server, &url[0]) != CELIX_SUCCESS) {
+        snprintf(url, MAX_LOCALNODE_LENGTH, "http://%s:%s/%s", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT, DEFAULT_SERVER_PATH);
+    }
+
+    while (watcher->running) {
+        // register own framework
+        if (discoveryShm_set(watcher->shmData, localNodePath, url) != CELIX_SUCCESS) {
+            logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot set local discovery registration.");
+        }
+
+        discoveryShmWatcher_syncEndpoints(discovery);
+        sleep(5);
+    }
+
+    return NULL;
+}
+
+celix_status_t discoveryShmWatcher_create(discovery_pt discovery) {
+    celix_status_t status = CELIX_SUCCESS;
+    shm_watcher_pt watcher = NULL;
+
+    watcher = calloc(1, sizeof(*watcher));
+
+    if (!watcher) {
+        status = CELIX_ENOMEM;
+    } else {
+        status = discoveryShm_attach(&(watcher->shmData));
+
+        if (status != CELIX_SUCCESS) {
+            logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_DEBUG, "Attaching to Shared Memory Failed. Trying to create.");
+
+            status = discoveryShm_create(&(watcher->shmData));
+
+            if (status != CELIX_SUCCESS) {
+                logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_ERROR, "Failed to create Shared Memory Segment.");
+            }
+        }
+
+        if (status == CELIX_SUCCESS) {
+            discovery->watcher = watcher;
+        }
+        else{
+        	discovery->watcher = NULL;
+        	free(watcher);
+        }
+
+    }
+
+    if (status == CELIX_SUCCESS) {
+        status += celixThreadMutex_create(&watcher->watcherLock, NULL);
+        status += celixThreadMutex_lock(&watcher->watcherLock);
+        watcher->running = true;
+        status += celixThread_create(&watcher->watcherThread, NULL, discoveryShmWatcher_run, discovery);
+        status += celixThreadMutex_unlock(&watcher->watcherLock);
+    }
+
+    return status;
+}
+
+celix_status_t discoveryShmWatcher_destroy(discovery_pt discovery) {
+    celix_status_t status;
+    shm_watcher_pt watcher = discovery->watcher;
+    char localNodePath[MAX_LOCALNODE_LENGTH];
+
+    celixThreadMutex_lock(&watcher->watcherLock);
+    watcher->running = false;
+    celixThreadMutex_unlock(&watcher->watcherLock);
+
+    celixThread_join(watcher->watcherThread, NULL);
+
+    // remove own framework
+    status = discoveryShmWatcher_getLocalNodePath(discovery->context, &localNodePath[0]);
+
+    if (status == CELIX_SUCCESS) {
+        status = discoveryShm_remove(watcher->shmData, localNodePath);
+    }
+
+    if (status == CELIX_SUCCESS) {
+        discoveryShm_detach(watcher->shmData);
+        free(watcher);
+    }
+    else {
+        logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot remove local discovery registration.");
+    }
+
+
+    return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_shmWatcher.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shmWatcher.h b/remote_services/discovery_shm/src/discovery_shmWatcher.h
new file mode 100644
index 0000000..ff70f72
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_shmWatcher.h
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * shm_watcher.h
+ *
+ * \date       30 Sep 2014
+ * \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright  Apache License, Version 2.0
+ */
+
+#ifndef DISCOVERY_SHM_WATCHER_H_
+#define DISCOVERY_SHM_WATCHER_H_
+
+#include "celix_errno.h"
+#include "discovery.h"
+#include "endpoint_discovery_poller.h"
+
+typedef struct shm_watcher *shm_watcher_pt;
+
+celix_status_t discoveryShmWatcher_create(discovery_pt discovery);
+celix_status_t discoveryShmWatcher_destroy(discovery_pt discovery);
+
+
+#endif /* DISCOVERY_SHM_WATCHER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/CMakeLists.txt b/remote_services/examples/CMakeLists.txt
index c7c5444..2b1f35f 100644
--- a/remote_services/examples/CMakeLists.txt
+++ b/remote_services/examples/CMakeLists.txt
@@ -17,6 +17,7 @@
 
 celix_subproject(RSA_EXAMPLES "Option to enable building the RSA examples" ON DEPS LAUNCHER shell_tui log_writer RSA_TOPOLOGY_MANAGER)
 if (RSA_EXAMPLES)
+    add_subdirectory(calculator_api)
     add_subdirectory(calculator_service)
     add_subdirectory(calculator_shell)
 
@@ -47,13 +48,13 @@ if (RSA_EXAMPLES)
         add_deploy(remote-services-dfi 
             NAME "server"
             GROUP "remote-services/remote-services-dfi"
-            BUNDLES discovery_etcd topology_manager remote_service_admin_dfi calculator Celix::shell Celix::shell_tui log_service log_writer
+            BUNDLES discovery_etcd topology_manager remote_service_admin_dfi calculator Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout
         )
 
         add_deploy("remote-services-dfi-client" 
             NAME "client"
             GROUP "remote-services/remote-services-dfi"
-            BUNDLES topology_manager remote_service_admin_dfi Celix::shell Celix::shell_tui log_service log_writer calculator_shell discovery_etcd
+            BUNDLES topology_manager remote_service_admin_dfi Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout calculator_shell discovery_etcd
         )
     endif ()
 endif (RSA_EXAMPLES)

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_api/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_api/CMakeLists.txt b/remote_services/examples/calculator_api/CMakeLists.txt
new file mode 100644
index 0000000..76acfa7
--- /dev/null
+++ b/remote_services/examples/calculator_api/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+add_library(calculator_api INTERFACE)
+target_include_directories(calculator_api INTERFACE include)
+set_target_properties(calculator_api PROPERTIES
+    "INTERFACE_CALCULATOR_DESCRIPTOR"
+    "${CMAKE_CURRENT_LIST_DIR}/include/org.apache.celix.calc.api.Calculator2.descriptor")
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_api/include/calculator_service.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_api/include/calculator_service.h b/remote_services/examples/calculator_api/include/calculator_service.h
new file mode 100644
index 0000000..8e2f0dc
--- /dev/null
+++ b/remote_services/examples/calculator_api/include/calculator_service.h
@@ -0,0 +1,56 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * calculator_service.h
+ *
+ *  \date       Oct 5, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef CALCULATOR_SERVICE_H_
+#define CALCULATOR_SERVICE_H_
+
+#define CALCULATOR_SERVICE "org.apache.celix.calc.api.Calculator"
+#define CALCULATOR2_SERVICE "org.apache.celix.calc.api.Calculator2"
+
+
+typedef struct calculator *calculator_pt;
+
+typedef struct calculator_service *calculator_service_pt;
+
+/*
+ * The calculator service definition corresponds to the following Java interface:
+ *
+ * interface Calculator {
+ * 	 double add(double a, double b);
+ * 	 double sub(double a, double b);
+ * 	 double sqrt(double a);
+ * }
+ */
+struct calculator_service {
+	calculator_pt calculator;
+	int (*add)(calculator_pt calculator, double a, double b, double *result);
+	int (*sub)(calculator_pt calculator, double a, double b, double *result);
+  int (*sqrt)(calculator_pt calculator, double a, double *result);
+};
+
+
+
+#endif /* CALCULATOR_SERVICE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
new file mode 100644
index 0000000..b784838
--- /dev/null
+++ b/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
@@ -0,0 +1,11 @@
+:header
+type=interface
+name=calculator
+version=1.3.0
+:annotations
+classname=org.example.Calculator
+:types
+:methods
+add(DD)D=add(#am=handle;PDD#am=pre;*D)N
+sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
+sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/CMakeLists.txt b/remote_services/examples/calculator_service/CMakeLists.txt
index 5e8040c..ff4d2d7 100644
--- a/remote_services/examples/calculator_service/CMakeLists.txt
+++ b/remote_services/examples/calculator_service/CMakeLists.txt
@@ -15,21 +15,15 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories("../../../utils/public/include")
-include_directories("../../utils/public/include")
-include_directories("../../remote_service_admin/public/include")
-include_directories("private/include")
-include_directories("public/include")
-
-add_bundle(calculator SOURCES
-	private/src/calculator_impl
-	private/src/calculator_activator
-    
-    private/include/calculator_impl.h
-
+add_bundle(calculator
+	SOURCES
+		src/calculator_impl
+		src/calculator_activator
     SYMBOLIC_NAME "apache_celix_remoting_calculator_impl"
     VERSION 0.0.1
 )
+target_include_directories(calculator PRIVATE src)
+target_link_libraries(calculator PRIVATE Celix::remote_service_admin_api calculator_api)
 
-bundle_files(calculator public/include/org.apache.celix.calc.api.Calculator2.descriptor
-    DESTINATION .)
+get_target_property(DESCR calculator_api INTERFACE_CALCULATOR_DESCRIPTOR)
+bundle_files(calculator ${DESCR} DESTINATION .)


[13/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_descriptor_common.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_descriptor_common.h b/remote_services/discovery_common/include/endpoint_descriptor_common.h
new file mode 100644
index 0000000..a186a18
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_descriptor_common.h
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_descriptor_common.h
+ *
+ * \date		Aug 8, 2014
+ * \author		<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DESCRIPTOR_COMMON_H_
+#define ENDPOINT_DESCRIPTOR_COMMON_H_
+
+/*
+ * Private constant & enum definitions for endpoint descriptor reader and writer, not needed for normal usage of the reader and writer.
+ */
+
+typedef enum {
+    VALUE_TYPE_STRING,
+    VALUE_TYPE_LONG,
+    VALUE_TYPE_DOUBLE,
+    VALUE_TYPE_FLOAT,
+    VALUE_TYPE_INTEGER,
+    VALUE_TYPE_BYTE,
+    VALUE_TYPE_CHAR,
+    VALUE_TYPE_BOOLEAN,
+    VALUE_TYPE_SHORT,
+} valueType;
+
+static const __attribute__((unused)) xmlChar* XML = (const xmlChar*) "xml";
+static const __attribute__((unused)) xmlChar* XMLNS = (const xmlChar*) "http://www.osgi.org/xmlns/rsa/v1.0.0";
+
+static const __attribute__((unused)) xmlChar* ENDPOINT_DESCRIPTIONS = (const xmlChar*) "endpoint-descriptions";
+static const xmlChar* ENDPOINT_DESCRIPTION = (const xmlChar*) "endpoint-description";
+
+static const xmlChar* ARRAY = (const xmlChar*) "array";
+static const __attribute__((unused)) xmlChar* LIST = (const xmlChar*) "list";
+static const __attribute__((unused)) xmlChar* SET = (const xmlChar*) "set";
+
+static const xmlChar* PROPERTY = (const xmlChar*) "property";
+static const xmlChar* NAME = (const xmlChar*) "name";
+static const xmlChar* VALUE = (const xmlChar*) "value";
+static const xmlChar* VALUE_TYPE = (const xmlChar*) "value-type";
+
+#endif /* ENDPOINT_DESCRIPTOR_COMMON_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_descriptor_reader.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_descriptor_reader.h b/remote_services/discovery_common/include/endpoint_descriptor_reader.h
new file mode 100644
index 0000000..7a05d9e
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_descriptor_reader.h
@@ -0,0 +1,42 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_descriptor_reader.h
+ *
+ *  \date       26 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DESCRIPTOR_READER_H_
+#define ENDPOINT_DESCRIPTOR_READER_H_
+
+#include "endpoint_discovery_poller.h"
+#include "celix_errno.h"
+#include "array_list.h"
+
+typedef struct endpoint_descriptor_reader *endpoint_descriptor_reader_pt;
+
+celix_status_t endpointDescriptorReader_create(endpoint_discovery_poller_pt poller, endpoint_descriptor_reader_pt *reader);
+celix_status_t endpointDescriptorReader_destroy(endpoint_descriptor_reader_pt reader);
+
+celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_pt reader, char *document, array_list_pt *endpoints);
+
+
+#endif /* ENDPOINT_DESCRIPTOR_READER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_descriptor_writer.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_descriptor_writer.h b/remote_services/discovery_common/include/endpoint_descriptor_writer.h
new file mode 100644
index 0000000..3c5a9be
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_descriptor_writer.h
@@ -0,0 +1,39 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_descriptor_writer.h
+ *
+ *  \date       26 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DESCRIPTOR_WRITER_H_
+#define ENDPOINT_DESCRIPTOR_WRITER_H_
+
+#include "celix_errno.h"
+#include "array_list.h"
+
+typedef struct endpoint_descriptor_writer *endpoint_descriptor_writer_pt;
+
+celix_status_t endpointDescriptorWriter_create(endpoint_descriptor_writer_pt *writer);
+celix_status_t endpointDescriptorWriter_destroy(endpoint_descriptor_writer_pt writer);
+celix_status_t endpointDescriptorWriter_writeDocument(endpoint_descriptor_writer_pt writer, array_list_pt endpoints, char **document);
+
+#endif /* ENDPOINT_DESCRIPTOR_WRITER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_discovery_poller.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_discovery_poller.h b/remote_services/discovery_common/include/endpoint_discovery_poller.h
new file mode 100644
index 0000000..d344e55
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_discovery_poller.h
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_discovery_poller.h
+ *
+ * \date       3 Jul 2014
+ * \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright  Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DISCOVERY_POLLER_H_
+#define ENDPOINT_DISCOVERY_POLLER_H_
+
+#include "celix_errno.h"
+#include "discovery.h"
+#include "log_helper.h"
+
+struct endpoint_discovery_poller {
+    discovery_pt discovery;
+    hash_map_pt entries;
+    log_helper_pt* loghelper;
+
+    celix_thread_mutex_t pollerLock;
+    celix_thread_t pollerThread;
+
+    unsigned int poll_interval;
+    volatile bool running;
+};
+
+typedef struct endpoint_discovery_poller *endpoint_discovery_poller_pt;
+
+celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller);
+celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller);
+
+celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url);
+celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url);
+
+celix_status_t endpointDiscoveryPoller_getDiscoveryEndpoints(endpoint_discovery_poller_pt poller, array_list_pt urls);
+
+#endif /* ENDPOINT_DISCOVERY_POLLER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_discovery_server.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_discovery_server.h b/remote_services/discovery_common/include/endpoint_discovery_server.h
new file mode 100644
index 0000000..51082b5
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_discovery_server.h
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_discovery_server.h
+ *
+ * \date		Aug 12, 2014
+ * \author		<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DISCOVERY_SERVER_H_
+#define ENDPOINT_DISCOVERY_SERVER_H_
+
+#include "celix_errno.h"
+#include "discovery.h"
+
+typedef struct endpoint_discovery_server *endpoint_discovery_server_pt;
+
+/**
+ * Creates and starts a new instance of an endpoint discovery server.
+ *
+ * @param discovery [in] the discovery service itself;
+ * @param context [in] the bundle context;
+ * @param server [out] the pointer to the created instance.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server);
+
+/**
+ * Stops and destroys a given instance of an endpoint discovery server.
+ *
+ * @param server [in] the pointer to the instance to destroy.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt server);
+
+/**
+ * Adds a given endpoint description to expose through the given discovery server.
+ *
+ * @param server [in] the endpoint discovery server to expose the endpoint through;
+ * @param endpoint [in] the endpoint description to expose.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint);
+
+/**
+ * Removes a given endpoint description from exposure through the given discovery server.
+ *
+ * @param server [in] the endpoint discovery server to remove the endpoint from;
+ * @param endpoint [in] the endpoint description to remove.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_removeEndpoint( endpoint_discovery_server_pt server, endpoint_description_pt endpoint);
+
+/**
+ * Returns the url, which is used by the discovery server to announce the endpoints
+ *
+ * @param server [in] the endpoint discovery server to retrieve the url from
+ * @param url [out] url which is used to announce the endpoints.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_getUrl(endpoint_discovery_server_pt server, char* url);
+
+
+#endif /* ENDPOINT_DISCOVERY_SERVER_H_ */


[17/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/psa_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/psa_activator.c b/pubsub/pubsub_admin_udp_mc/src/psa_activator.c
new file mode 100644
index 0000000..cd4ee07
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/psa_activator.c
@@ -0,0 +1,141 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * psa_activator.c
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+#include "service_tracker.h"
+
+#include "pubsub_admin_impl.h"
+
+struct activator {
+	pubsub_admin_pt admin;
+	pubsub_admin_service_pt adminService;
+	service_registration_pt registration;
+	service_tracker_pt serializerTracker;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator;
+
+	activator = calloc(1, sizeof(*activator));
+	if (!activator) {
+		status = CELIX_ENOMEM;
+	}
+	else{
+		*userData = activator;
+
+		status = pubsubAdmin_create(context, &(activator->admin));
+
+		if(status == CELIX_SUCCESS){
+			service_tracker_customizer_pt customizer = NULL;
+			status = serviceTrackerCustomizer_create(activator->admin,
+					NULL,
+					pubsubAdmin_serializerAdded,
+					NULL,
+					pubsubAdmin_serializerRemoved,
+					&customizer);
+			if(status == CELIX_SUCCESS){
+				status = serviceTracker_create(context, PUBSUB_SERIALIZER_SERVICE, customizer, &(activator->serializerTracker));
+				if(status != CELIX_SUCCESS){
+					serviceTrackerCustomizer_destroy(customizer);
+					pubsubAdmin_destroy(activator->admin);
+				}
+			}
+			else{
+				pubsubAdmin_destroy(activator->admin);
+			}
+		}
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	pubsub_admin_service_pt pubsubAdminSvc = calloc(1, sizeof(*pubsubAdminSvc));
+
+	if (!pubsubAdminSvc) {
+		status = CELIX_ENOMEM;
+	}
+	else{
+		pubsubAdminSvc->admin = activator->admin;
+
+		pubsubAdminSvc->addPublication = pubsubAdmin_addPublication;
+		pubsubAdminSvc->removePublication = pubsubAdmin_removePublication;
+
+		pubsubAdminSvc->addSubscription = pubsubAdmin_addSubscription;
+		pubsubAdminSvc->removeSubscription = pubsubAdmin_removeSubscription;
+
+		pubsubAdminSvc->closeAllPublications = pubsubAdmin_closeAllPublications;
+		pubsubAdminSvc->closeAllSubscriptions = pubsubAdmin_closeAllSubscriptions;
+
+		pubsubAdminSvc->matchEndpoint = pubsubAdmin_matchEndpoint;
+
+		activator->adminService = pubsubAdminSvc;
+
+		status = bundleContext_registerService(context, PUBSUB_ADMIN_SERVICE, pubsubAdminSvc, NULL, &activator->registration);
+
+		status += serviceTracker_open(activator->serializerTracker);
+
+	}
+
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	status += serviceTracker_close(activator->serializerTracker);
+	status += serviceRegistration_unregister(activator->registration);
+
+	activator->registration = NULL;
+
+	free(activator->adminService);
+	activator->adminService = NULL;
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	serviceTracker_destroy(activator->serializerTracker);
+	pubsubAdmin_destroy(activator->admin);
+	activator->admin = NULL;
+
+	free(activator);
+
+	return status;
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
new file mode 100644
index 0000000..1fbdb08
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
@@ -0,0 +1,1039 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * pubsub_admin_impl.c
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef ANDROID
+#include <ifaddrs.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include "constants.h"
+#include "utils.h"
+#include "hash_map.h"
+#include "array_list.h"
+#include "bundle_context.h"
+#include "bundle.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "log_helper.h"
+#include "log_service.h"
+#include "celix_threads.h"
+#include "service_factory.h"
+
+#include "pubsub_admin_impl.h"
+#include "topic_subscription.h"
+#include "topic_publication.h"
+#include "pubsub_endpoint.h"
+#include "subscriber.h"
+#include "pubsub_admin_match.h"
+
+static const char *DEFAULT_MC_IP = "224.100.1.1";
+static char *DEFAULT_MC_PREFIX = "224.100";
+
+static celix_status_t pubsubAdmin_getIpAddress(const char* interface, char** ip);
+static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+
+static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc);
+static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication);
+static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication);
+
+celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*admin = calloc(1, sizeof(**admin));
+
+	if (!*admin) {
+		return CELIX_ENOMEM;
+	}
+
+	char *mc_ip = NULL;
+	char *if_ip = NULL;
+	int sendSocket = -1;
+
+	if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
+		logHelper_start((*admin)->loghelper);
+	}
+	const char *mc_ip_prop = NULL;
+	bundleContext_getProperty(context,PSA_IP , &mc_ip_prop);
+	if(mc_ip_prop) {
+		mc_ip = strdup(mc_ip_prop);
+	}
+
+#ifndef ANDROID
+	if (mc_ip == NULL) {
+		const char *mc_prefix = NULL;
+		const char *interface = NULL;
+		int b0 = 0, b1 = 0, b2 = 0, b3 = 0;
+		bundleContext_getProperty(context,PSA_MULTICAST_IP_PREFIX , &mc_prefix);
+		if(mc_prefix == NULL) {
+			mc_prefix = DEFAULT_MC_PREFIX;
+		}
+
+		bundleContext_getProperty(context, PSA_ITF, &interface);
+		if (pubsubAdmin_getIpAddress(interface, &if_ip) != CELIX_SUCCESS) {
+			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: Could not retrieve IP address for interface %s", interface);
+		}
+
+		printf("IP Detected : %s\n", if_ip);
+		if(if_ip && sscanf(if_ip, "%i.%i.%i.%i", &b0, &b1, &b2, &b3) != 4) {
+			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: Could not parse IP address %s", if_ip);
+			b2 = 1;
+			b3 = 1;
+		}
+
+		asprintf(&mc_ip, "%s.%d.%d",mc_prefix, b2, b3);
+
+		sendSocket = socket(AF_INET, SOCK_DGRAM, 0);
+		if(sendSocket == -1) {
+			perror("pubsubAdmin_create:socket");
+			status = CELIX_SERVICE_EXCEPTION;
+		}
+
+		if(status == CELIX_SUCCESS){
+			char loop = 1;
+			if(setsockopt(sendSocket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != 0) {
+				perror("pubsubAdmin_create:setsockopt(IP_MULTICAST_LOOP)");
+				status = CELIX_SERVICE_EXCEPTION;
+			}
+		}
+
+		if(status == CELIX_SUCCESS){
+			struct in_addr multicast_interface;
+			inet_aton(if_ip, &multicast_interface);
+			if(setsockopt(sendSocket,  IPPROTO_IP, IP_MULTICAST_IF, &multicast_interface, sizeof(multicast_interface)) != 0) {
+				perror("pubsubAdmin_create:setsockopt(IP_MULTICAST_IF)");
+				status = CELIX_SERVICE_EXCEPTION;
+			}
+		}
+
+	}
+
+
+	if(status != CELIX_SUCCESS){
+		logHelper_stop((*admin)->loghelper);
+		logHelper_destroy(&((*admin)->loghelper));
+		if(sendSocket >=0){
+			close(sendSocket);
+		}
+		if(if_ip != NULL){
+			free(if_ip);
+		}
+		if(mc_ip != NULL){
+			free(mc_ip);
+		}
+		return status;
+	}
+	else{
+		(*admin)->sendSocket = sendSocket;
+	}
+
+#endif
+
+	(*admin)->bundle_context= context;
+	(*admin)->localPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	(*admin)->subscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	(*admin)->pendingSubscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	(*admin)->externalPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	(*admin)->topicSubscriptionsPerSerializer = hashMap_create(NULL, NULL, NULL, NULL);
+	(*admin)->topicPublicationsPerSerializer  = hashMap_create(NULL, NULL, NULL, NULL);
+	arrayList_create(&((*admin)->noSerializerSubscriptions));
+	arrayList_create(&((*admin)->noSerializerPublications));
+	arrayList_create(&((*admin)->serializerList));
+
+	celixThreadMutex_create(&(*admin)->localPublicationsLock, NULL);
+	celixThreadMutex_create(&(*admin)->subscriptionsLock, NULL);
+	celixThreadMutex_create(&(*admin)->externalPublicationsLock, NULL);
+	celixThreadMutex_create(&(*admin)->serializerListLock, NULL);
+	celixThreadMutex_create(&(*admin)->usedSerializersLock, NULL);
+
+	celixThreadMutexAttr_create(&(*admin)->noSerializerPendingsAttr);
+	celixThreadMutexAttr_settype(&(*admin)->noSerializerPendingsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+	celixThreadMutex_create(&(*admin)->noSerializerPendingsLock, &(*admin)->noSerializerPendingsAttr);
+
+	celixThreadMutexAttr_create(&(*admin)->pendingSubscriptionsAttr);
+	celixThreadMutexAttr_settype(&(*admin)->pendingSubscriptionsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+	celixThreadMutex_create(&(*admin)->pendingSubscriptionsLock, &(*admin)->pendingSubscriptionsAttr);
+
+	if (if_ip != NULL) {
+		logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_UDP_MC: Using %s as interface for multicast communication", if_ip);
+		(*admin)->ifIpAddress = if_ip;
+	} else {
+		(*admin)->ifIpAddress = strdup("127.0.0.1");
+	}
+
+	if (mc_ip != NULL) {
+		logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_UDP_MC: Using %s for service annunciation", mc_ip);
+		(*admin)->mcIpAddress = mc_ip;
+	}
+	else {
+		logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: No IP address for service annunciation set. Using %s", DEFAULT_MC_IP);
+		(*admin)->mcIpAddress = strdup(DEFAULT_MC_IP);
+	}
+
+	return status;
+}
+
+
+celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin)
+{
+	celix_status_t status = CELIX_SUCCESS;
+
+	free(admin->mcIpAddress);
+	free(admin->ifIpAddress);
+
+	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
+	hash_map_iterator_pt iter = hashMapIterator_create(admin->pendingSubscriptions);
+	while(hashMapIterator_hasNext(iter)){
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		free((char*)hashMapEntry_getKey(entry));
+		arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(admin->pendingSubscriptions,false,false);
+	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
+
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+	hashMap_destroy(admin->subscriptions,false,false);
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	celixThreadMutex_lock(&admin->localPublicationsLock);
+	hashMap_destroy(admin->localPublications,true,false);
+	celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+	celixThreadMutex_lock(&admin->externalPublicationsLock);
+	iter = hashMapIterator_create(admin->externalPublications);
+	while(hashMapIterator_hasNext(iter)){
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		free((char*)hashMapEntry_getKey(entry));
+		arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(admin->externalPublications,false,false);
+	celixThreadMutex_unlock(&admin->externalPublicationsLock);
+
+	celixThreadMutex_lock(&admin->serializerListLock);
+	arrayList_destroy(admin->serializerList);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+	celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+	arrayList_destroy(admin->noSerializerSubscriptions);
+	arrayList_destroy(admin->noSerializerPublications);
+	celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+
+	celixThreadMutex_lock(&admin->usedSerializersLock);
+
+	iter = hashMapIterator_create(admin->topicSubscriptionsPerSerializer);
+	while(hashMapIterator_hasNext(iter)){
+		arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(admin->topicSubscriptionsPerSerializer,false,false);
+
+	iter = hashMapIterator_create(admin->topicPublicationsPerSerializer);
+	while(hashMapIterator_hasNext(iter)){
+		arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(admin->topicPublicationsPerSerializer,false,false);
+
+	celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+	celixThreadMutex_destroy(&admin->usedSerializersLock);
+	celixThreadMutex_destroy(&admin->serializerListLock);
+
+	celixThreadMutexAttr_destroy(&admin->noSerializerPendingsAttr);
+	celixThreadMutex_destroy(&admin->noSerializerPendingsLock);
+
+	celixThreadMutex_destroy(&admin->pendingSubscriptionsLock);
+	celixThreadMutexAttr_destroy(&admin->pendingSubscriptionsAttr);
+
+	celixThreadMutex_destroy(&admin->subscriptionsLock);
+	celixThreadMutex_destroy(&admin->localPublicationsLock);
+	celixThreadMutex_destroy(&admin->externalPublicationsLock);
+
+	logHelper_stop(admin->loghelper);
+
+	logHelper_destroy(&admin->loghelper);
+
+	free(admin);
+
+	return status;
+}
+
+static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+
+	topic_subscription_pt any_sub = hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
+
+	if(any_sub==NULL){
+
+		int i;
+		pubsub_serializer_service_t *best_serializer = NULL;
+		if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
+			status = pubsub_topicSubscriptionCreate(admin->bundle_context, admin->ifIpAddress, PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, PUBSUB_ANY_SUB_TOPIC, best_serializer, &any_sub);
+		}
+		else{
+			printf("PSA_UDP_MC: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
+			celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+			arrayList_add(admin->noSerializerSubscriptions,subEP);
+			celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+		}
+
+		if (status == CELIX_SUCCESS){
+
+			/* Connect all internal publishers */
+			celixThreadMutex_lock(&admin->localPublicationsLock);
+			hash_map_iterator_pt lp_iter =hashMapIterator_create(admin->localPublications);
+			while(hashMapIterator_hasNext(lp_iter)){
+				service_factory_pt factory = (service_factory_pt)hashMapIterator_nextValue(lp_iter);
+				topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
+				array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
+
+				if(topic_publishers!=NULL){
+					for(i=0;i<arrayList_size(topic_publishers);i++){
+						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
+						if(pubEP->endpoint !=NULL){
+							status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
+						}
+					}
+					arrayList_destroy(topic_publishers);
+				}
+			}
+			hashMapIterator_destroy(lp_iter);
+			celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+			/* Connect also all external publishers */
+			celixThreadMutex_lock(&admin->externalPublicationsLock);
+			hash_map_iterator_pt extp_iter =hashMapIterator_create(admin->externalPublications);
+			while(hashMapIterator_hasNext(extp_iter)){
+				array_list_pt ext_pub_list = (array_list_pt)hashMapIterator_nextValue(extp_iter);
+				if(ext_pub_list!=NULL){
+					for(i=0;i<arrayList_size(ext_pub_list);i++){
+						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+						if(pubEP->endpoint !=NULL){
+							status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
+						}
+					}
+				}
+			}
+			hashMapIterator_destroy(extp_iter);
+			celixThreadMutex_unlock(&admin->externalPublicationsLock);
+
+
+			pubsub_topicSubscriptionAddSubscriber(any_sub,subEP);
+
+			status += pubsub_topicSubscriptionStart(any_sub);
+
+		}
+
+		if (status == CELIX_SUCCESS){
+			hashMap_put(admin->subscriptions,strdup(PUBSUB_ANY_SUB_TOPIC),any_sub);
+			connectTopicPubSubToSerializer(admin, best_serializer, any_sub, false);
+		}
+
+	}
+
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	return status;
+}
+
+celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_UDP_MC: Received subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope,subEP->topic);
+
+	if(strcmp(subEP->topic,PUBSUB_ANY_SUB_TOPIC)==0){
+		return pubsubAdmin_addAnySubscription(admin,subEP);
+	}
+
+	/* Check if we already know some publisher about this topic, otherwise let's put the subscription in the pending hashmap */
+	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+	celixThreadMutex_lock(&admin->localPublicationsLock);
+	celixThreadMutex_lock(&admin->externalPublicationsLock);
+
+	char* scope_topic = createScopeTopicKey(subEP->scope,subEP->topic);
+
+	service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
+	array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
+
+	if(factory==NULL && ext_pub_list==NULL){ //No (local or external) publishers yet for this topic
+		pubsubAdmin_addSubscriptionToPendingList(admin,subEP);
+	}
+	else{
+		int i;
+		topic_subscription_pt subscription = hashMap_get(admin->subscriptions, scope_topic);
+
+		if(subscription == NULL) {
+			pubsub_serializer_service_t *best_serializer = NULL;
+			if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
+				status += pubsub_topicSubscriptionCreate(admin->bundle_context,admin->ifIpAddress, subEP->scope, subEP->topic, best_serializer, &subscription);
+			}
+			else{
+				printf("PSA_UDP_MC: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
+				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+				arrayList_add(admin->noSerializerSubscriptions,subEP);
+				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+			}
+
+			if (status==CELIX_SUCCESS){
+
+				/* Try to connect internal publishers */
+				if(factory!=NULL){
+					topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
+					array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
+
+					if(topic_publishers!=NULL){
+						for(i=0;i<arrayList_size(topic_publishers);i++){
+							pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
+							if(pubEP->endpoint !=NULL){
+								status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
+							}
+						}
+						arrayList_destroy(topic_publishers);
+					}
+
+				}
+
+				/* Look also for external publishers */
+				if(ext_pub_list!=NULL){
+					for(i=0;i<arrayList_size(ext_pub_list);i++){
+						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+						if(pubEP->endpoint !=NULL){
+							status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
+						}
+					}
+				}
+
+				pubsub_topicSubscriptionAddSubscriber(subscription,subEP);
+
+				status += pubsub_topicSubscriptionStart(subscription);
+
+			}
+
+			if(status==CELIX_SUCCESS){
+
+				hashMap_put(admin->subscriptions,strdup(scope_topic),subscription);
+
+				connectTopicPubSubToSerializer(admin, best_serializer, subscription, false);
+			}
+		}
+
+		if (status == CELIX_SUCCESS){
+			pubsub_topicIncreaseNrSubscribers(subscription);
+		}
+	}
+
+	free(scope_topic);
+	celixThreadMutex_unlock(&admin->externalPublicationsLock);
+	celixThreadMutex_unlock(&admin->localPublicationsLock);
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_UDP_MC: Removing subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope, subEP->topic);
+
+	char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
+
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+	topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
+	if(sub!=NULL){
+		pubsub_topicDecreaseNrSubscribers(sub);
+		if(pubsub_topicGetNrSubscribers(sub) == 0) {
+			status = pubsub_topicSubscriptionRemoveSubscriber(sub,subEP);
+		}
+	}
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	if(sub==NULL){
+		/* Maybe the endpoint was pending */
+		celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+		if(!arrayList_removeElement(admin->noSerializerSubscriptions, subEP)){
+			status = CELIX_ILLEGAL_STATE;
+		}
+		celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+	}
+
+	free(scope_topic);
+
+
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_UDP_MC: Received publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->scope, pubEP->topic);
+
+	const char* fwUUID = NULL;
+
+	bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+	if(fwUUID==NULL){
+		printf("PSA_UDP_MC: Cannot retrieve fwUUID.\n");
+		return CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+	char* scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
+
+	if ((strcmp(pubEP->frameworkUUID, fwUUID) == 0) && (pubEP->endpoint == NULL)) {
+
+		celixThreadMutex_lock(&admin->localPublicationsLock);
+
+		service_factory_pt factory = (service_factory_pt) hashMap_get(admin->localPublications, scope_topic);
+
+		if (factory == NULL) {
+			topic_publication_pt pub = NULL;
+			pubsub_serializer_service_t *best_serializer = NULL;
+			if( (status=pubsubAdmin_getBestSerializer(admin, pubEP, &best_serializer)) == CELIX_SUCCESS){
+				status = pubsub_topicPublicationCreate(admin->sendSocket, pubEP, best_serializer, admin->mcIpAddress, &pub);
+			}
+			else{
+				printf("PSA_UDP_MC: Cannot find a serializer for publishing topic %s. Adding it to pending list.\n", pubEP->topic);
+				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+				arrayList_add(admin->noSerializerPublications,pubEP);
+				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+			}
+
+			if (status == CELIX_SUCCESS) {
+				status = pubsub_topicPublicationStart(admin->bundle_context, pub, &factory);
+				if (status == CELIX_SUCCESS && factory != NULL) {
+					hashMap_put(admin->localPublications, strdup(scope_topic), factory);
+					connectTopicPubSubToSerializer(admin, best_serializer, pub, true);
+				}
+			} else {
+				printf("PSA_UDP_MC: Cannot create a topicPublication for scope=%s, topic=%s (bundle %ld).\n", pubEP->scope, pubEP->topic, pubEP->serviceID);
+			}
+		} else {
+			//just add the new EP to the list
+			topic_publication_pt pub = (topic_publication_pt) factory->handle;
+			pubsub_topicPublicationAddPublisherEP(pub, pubEP);
+		}
+
+		celixThreadMutex_unlock(&admin->localPublicationsLock);
+	}
+	else{
+
+		celixThreadMutex_lock(&admin->externalPublicationsLock);
+		array_list_pt ext_pub_list = (array_list_pt) hashMap_get(admin->externalPublications, scope_topic);
+		if (ext_pub_list == NULL) {
+			arrayList_create(&ext_pub_list);
+			hashMap_put(admin->externalPublications, strdup(scope_topic), ext_pub_list);
+		}
+
+		arrayList_add(ext_pub_list, pubEP);
+
+		celixThreadMutex_unlock(&admin->externalPublicationsLock);
+	}
+
+	/* Re-evaluate the pending subscriptions */
+	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
+
+	hash_map_entry_pt pendingSub = hashMap_getEntry(admin->pendingSubscriptions, scope_topic);
+	if (pendingSub != NULL) { //There were pending subscription for the just published topic. Let's connect them.
+		char* topic = (char*) hashMapEntry_getKey(pendingSub);
+		array_list_pt pendingSubList = (array_list_pt) hashMapEntry_getValue(pendingSub);
+		int i;
+		for (i = 0; i < arrayList_size(pendingSubList); i++) {
+			pubsub_endpoint_pt subEP = (pubsub_endpoint_pt) arrayList_get(pendingSubList, i);
+			pubsubAdmin_addSubscription(admin, subEP);
+		}
+		hashMap_remove(admin->pendingSubscriptions, scope_topic);
+		arrayList_clear(pendingSubList);
+		arrayList_destroy(pendingSubList);
+		free(topic);
+	}
+
+	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
+
+	/* Connect the new publisher to the subscription for his topic, if there is any */
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+
+	topic_subscription_pt sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, scope_topic);
+	if (sub != NULL && pubEP->endpoint != NULL) {
+		pubsub_topicSubscriptionAddConnectPublisherToPendingList(sub, pubEP->endpoint);
+	}
+
+	/* And check also for ANY subscription */
+	topic_subscription_pt any_sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, PUBSUB_ANY_SUB_TOPIC);
+	if (any_sub != NULL && pubEP->endpoint != NULL) {
+		pubsub_topicSubscriptionAddConnectPublisherToPendingList(any_sub, pubEP->endpoint);
+	}
+
+	free(scope_topic);
+
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
+	celix_status_t status = CELIX_SUCCESS;
+	int count = 0;
+
+	printf("PSA_UDP_MC: Removing publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->scope, pubEP->topic);
+
+	const char* fwUUID = NULL;
+
+	bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+	if(fwUUID==NULL){
+		printf("PSA_UDP_MC: Cannot retrieve fwUUID.\n");
+		return CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+	char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
+
+	if(strcmp(pubEP->frameworkUUID,fwUUID)==0){
+
+		celixThreadMutex_lock(&admin->localPublicationsLock);
+		service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
+		if(factory!=NULL){
+			topic_publication_pt pub = (topic_publication_pt)factory->handle;
+			pubsub_topicPublicationRemovePublisherEP(pub,pubEP);
+		}
+		celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+		if(factory==NULL){
+			/* Maybe the endpoint was pending */
+			celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+			if(!arrayList_removeElement(admin->noSerializerPublications, pubEP)){
+				status = CELIX_ILLEGAL_STATE;
+			}
+			celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+		}
+
+	}
+	else{
+
+		celixThreadMutex_lock(&admin->externalPublicationsLock);
+		array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
+		if(ext_pub_list!=NULL){
+			int i;
+			bool found = false;
+			for(i=0;!found && i<arrayList_size(ext_pub_list);i++){
+				pubsub_endpoint_pt p  = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+				found = pubsubEndpoint_equals(pubEP,p);
+				if (found){
+					arrayList_remove(ext_pub_list,i);
+				}
+			}
+			// Check if there are more publishers on the same endpoint (happens when 1 celix-instance with multiple bundles publish in same topic)
+			for(i=0; i<arrayList_size(ext_pub_list);i++) {
+				pubsub_endpoint_pt p  = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+				if (strcmp(pubEP->endpoint,p->endpoint) == 0) {
+					count++;
+				}
+			}
+
+			if(arrayList_size(ext_pub_list)==0){
+				hash_map_entry_pt entry = hashMap_getEntry(admin->externalPublications,scope_topic);
+				char* topic = (char*)hashMapEntry_getKey(entry);
+				array_list_pt list = (array_list_pt)hashMapEntry_getValue(entry);
+				hashMap_remove(admin->externalPublications,topic);
+				arrayList_destroy(list);
+				free(topic);
+			}
+		}
+
+		celixThreadMutex_unlock(&admin->externalPublicationsLock);
+	}
+
+	/* Check if this publisher was connected to one of our subscribers*/
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+
+	topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
+	if(sub!=NULL && pubEP->endpoint!=NULL && count == 0){
+		pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(sub,pubEP->endpoint);
+	}
+
+	/* And check also for ANY subscription */
+	topic_subscription_pt any_sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
+	if(any_sub!=NULL && pubEP->endpoint!=NULL && count == 0){
+		pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(any_sub,pubEP->endpoint);
+	}
+
+	free(scope_topic);
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char *scope, char* topic){
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_UDP_MC: Closing all publications for scope=%s,topic=%s\n", scope, topic);
+
+	celixThreadMutex_lock(&admin->localPublicationsLock);
+	char* scope_topic =createScopeTopicKey(scope, topic);
+	hash_map_entry_pt pubsvc_entry = (hash_map_entry_pt)hashMap_getEntry(admin->localPublications,scope_topic);
+	if(pubsvc_entry!=NULL){
+		char* key = (char*)hashMapEntry_getKey(pubsvc_entry);
+		service_factory_pt factory= (service_factory_pt)hashMapEntry_getValue(pubsvc_entry);
+		topic_publication_pt pub = (topic_publication_pt)factory->handle;
+		status += pubsub_topicPublicationStop(pub);
+		disconnectTopicPubSubFromSerializer(admin, pub, true);
+		status += pubsub_topicPublicationDestroy(pub);
+		hashMap_remove(admin->localPublications,scope_topic);
+		free(key);
+		free(factory);
+	}
+	free(scope_topic);
+	celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char *scope, char* topic){
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_UDP_MC: Closing all subscriptions\n");
+
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+	char* scope_topic =createScopeTopicKey(scope, topic);
+	hash_map_entry_pt sub_entry = (hash_map_entry_pt)hashMap_getEntry(admin->subscriptions,scope_topic);
+	if(sub_entry!=NULL){
+		char* topic = (char*)hashMapEntry_getKey(sub_entry);
+
+		topic_subscription_pt ts = (topic_subscription_pt)hashMapEntry_getValue(sub_entry);
+		status += pubsub_topicSubscriptionStop(ts);
+		disconnectTopicPubSubFromSerializer(admin, ts, false);
+		status += pubsub_topicSubscriptionDestroy(ts);
+		hashMap_remove(admin->subscriptions,topic);
+		free(topic);
+
+	}
+	free(scope_topic);
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	return status;
+
+}
+
+
+#ifndef ANDROID
+static celix_status_t pubsubAdmin_getIpAddress(const char* interface, char** ip) {
+	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+	struct ifaddrs *ifaddr, *ifa;
+	char host[NI_MAXHOST];
+
+	if (getifaddrs(&ifaddr) != -1)
+	{
+		for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+		{
+			if (ifa->ifa_addr == NULL)
+				continue;
+
+			if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+				if (interface == NULL) {
+					*ip = strdup(host);
+					status = CELIX_SUCCESS;
+				}
+				else if (strcmp(ifa->ifa_name, interface) == 0) {
+					*ip = strdup(host);
+					status = CELIX_SUCCESS;
+				}
+			}
+		}
+
+		freeifaddrs(ifaddr);
+	}
+
+	return status;
+}
+#endif
+
+static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	char* scope_topic =createScopeTopicKey(subEP->scope, subEP->topic);
+	array_list_pt pendingListPerTopic = hashMap_get(admin->pendingSubscriptions,scope_topic);
+	if(pendingListPerTopic==NULL){
+		arrayList_create(&pendingListPerTopic);
+		hashMap_put(admin->pendingSubscriptions,strdup(scope_topic),pendingListPerTopic);
+	}
+	arrayList_add(pendingListPerTopic,subEP);
+	free(scope_topic);
+
+	return status;
+}
+
+
+celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service){
+	/* Assumption: serializers are all available at startup.
+	 * If a new (possibly better) serializer is installed and started, already created topic_publications/subscriptions will not be destroyed and recreated */
+
+	celix_status_t status = CELIX_SUCCESS;
+	int i=0;
+
+	const char *serType = NULL;
+	serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
+	if(serType == NULL){
+		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
+		return CELIX_SERVICE_EXCEPTION;
+	}
+
+	pubsub_admin_pt admin = (pubsub_admin_pt)handle;
+	celixThreadMutex_lock(&admin->serializerListLock);
+	arrayList_add(admin->serializerList, reference);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+	/* Now let's re-evaluate the pending */
+	celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+
+	for(i=0;i<arrayList_size(admin->noSerializerSubscriptions);i++){
+		pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerSubscriptions,i);
+		pubsub_serializer_service_t *best_serializer = NULL;
+		pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
+		if(best_serializer != NULL){ /* Finally we have a valid serializer! */
+			pubsubAdmin_addSubscription(admin, ep);
+		}
+	}
+
+	for(i=0;i<arrayList_size(admin->noSerializerPublications);i++){
+		pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerPublications,i);
+		pubsub_serializer_service_t *best_serializer = NULL;
+		pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
+		if(best_serializer != NULL){ /* Finally we have a valid serializer! */
+			pubsubAdmin_addPublication(admin, ep);
+		}
+	}
+
+	celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+
+	printf("PSA_UDP_MC: %s serializer added\n",serType);
+
+	return status;
+}
+
+celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service){
+
+	pubsub_admin_pt admin = (pubsub_admin_pt)handle;
+	int i=0, j=0;
+	const char *serType = NULL;
+
+	serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
+	if(serType == NULL){
+		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
+		return CELIX_SERVICE_EXCEPTION;
+	}
+
+	celixThreadMutex_lock(&admin->serializerListLock);
+	/* Remove the serializer from the list */
+	arrayList_removeElement(admin->serializerList, reference);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+	celixThreadMutex_lock(&admin->usedSerializersLock);
+	array_list_pt topicPubList = (array_list_pt)hashMap_remove(admin->topicPublicationsPerSerializer, service);
+	array_list_pt topicSubList = (array_list_pt)hashMap_remove(admin->topicSubscriptionsPerSerializer, service);
+	celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+	/* Now destroy the topicPublications, but first put back the pubsub_endpoints back to the noSerializer pending list */
+	if(topicPubList!=NULL){
+		for(i=0;i<arrayList_size(topicPubList);i++){
+			topic_publication_pt topicPub = (topic_publication_pt)arrayList_get(topicPubList,i);
+			/* Stop the topic publication */
+			pubsub_topicPublicationStop(topicPub);
+			/* Get the endpoints that are going to be orphan */
+			array_list_pt pubList = pubsub_topicPublicationGetPublisherList(topicPub);
+			for(j=0;j<arrayList_size(pubList);j++){
+				pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubList,j);
+				/* Remove the publication */
+				pubsubAdmin_removePublication(admin, pubEP);
+				/* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
+				if(pubEP->endpoint!=NULL){
+					free(pubEP->endpoint);
+					pubEP->endpoint = NULL;
+				}
+				/* Add the orphan endpoint to the noSerializer pending list */
+				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+				arrayList_add(admin->noSerializerPublications,pubEP);
+				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+			}
+			arrayList_destroy(pubList);
+
+			/* Cleanup also the localPublications hashmap*/
+			celixThreadMutex_lock(&admin->localPublicationsLock);
+			hash_map_iterator_pt iter = hashMapIterator_create(admin->localPublications);
+			char *key = NULL;
+			service_factory_pt factory = NULL;
+			while(hashMapIterator_hasNext(iter)){
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+				factory = (service_factory_pt)hashMapEntry_getValue(entry);
+				topic_publication_pt pub = (topic_publication_pt)factory->handle;
+				if(pub==topicPub){
+					key = (char*)hashMapEntry_getKey(entry);
+					break;
+				}
+			}
+			hashMapIterator_destroy(iter);
+			if(key!=NULL){
+				hashMap_remove(admin->localPublications, key);
+				free(factory);
+				free(key);
+			}
+			celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+			/* Finally destroy the topicPublication */
+			pubsub_topicPublicationDestroy(topicPub);
+		}
+		arrayList_destroy(topicPubList);
+	}
+
+	/* Now destroy the topicSubscriptions, but first put back the pubsub_endpoints back to the noSerializer pending list */
+	if(topicSubList!=NULL){
+		for(i=0;i<arrayList_size(topicSubList);i++){
+			topic_subscription_pt topicSub = (topic_subscription_pt)arrayList_get(topicSubList,i);
+			/* Stop the topic subscription */
+			pubsub_topicSubscriptionStop(topicSub);
+			/* Get the endpoints that are going to be orphan */
+			array_list_pt subList = pubsub_topicSubscriptionGetSubscribersList(topicSub);
+			for(j=0;j<arrayList_size(subList);j++){
+				pubsub_endpoint_pt subEP = (pubsub_endpoint_pt)arrayList_get(subList,j);
+				/* Remove the subscription */
+				pubsubAdmin_removeSubscription(admin, subEP);
+				/* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
+				if(subEP->endpoint!=NULL){
+					free(subEP->endpoint);
+					subEP->endpoint = NULL;
+				}
+				/* Add the orphan endpoint to the noSerializer pending list */
+				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+				arrayList_add(admin->noSerializerSubscriptions,subEP);
+				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+			}
+
+			/* Cleanup also the subscriptions hashmap*/
+			celixThreadMutex_lock(&admin->subscriptionsLock);
+			hash_map_iterator_pt iter = hashMapIterator_create(admin->subscriptions);
+			char *key = NULL;
+			while(hashMapIterator_hasNext(iter)){
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+				topic_subscription_pt sub = (topic_subscription_pt)hashMapEntry_getValue(entry);
+				if(sub==topicSub){
+					key = (char*)hashMapEntry_getKey(entry);
+					break;
+				}
+			}
+			hashMapIterator_destroy(iter);
+			if(key!=NULL){
+				hashMap_remove(admin->subscriptions, key);
+				free(key);
+			}
+			celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+			/* Finally destroy the topicSubscription */
+			pubsub_topicSubscriptionDestroy(topicSub);
+		}
+		arrayList_destroy(topicSubList);
+	}
+
+	printf("PSA_UDP_MC: %s serializer removed\n",serType);
+
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&admin->serializerListLock);
+	status = pubsub_admin_match(endpoint->topic_props,PUBSUB_ADMIN_TYPE,admin->serializerList,score);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+	return status;
+}
+
+/* This one recall the same logic as in the match function */
+static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc){
+
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&admin->serializerListLock);
+	status = pubsub_admin_get_best_serializer(ep->topic_props, admin->serializerList, serSvc);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+	return status;
+
+}
+
+static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication){
+
+	celixThreadMutex_lock(&admin->usedSerializersLock);
+
+	hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
+	array_list_pt list = (array_list_pt)hashMap_get(map,serializer);
+	if(list==NULL){
+		arrayList_create(&list);
+		hashMap_put(map,serializer,list);
+	}
+	arrayList_add(list,topicPubSub);
+
+	celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+}
+
+static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication){
+
+	celixThreadMutex_lock(&admin->usedSerializersLock);
+
+	hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
+	hash_map_iterator_pt iter = hashMapIterator_create(map);
+	while(hashMapIterator_hasNext(iter)){
+		array_list_pt list = (array_list_pt)hashMapIterator_nextValue(iter);
+		if(arrayList_removeElement(list, topicPubSub)){ //Found it!
+			break;
+		}
+	}
+	hashMapIterator_destroy(iter);
+
+	celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.h b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.h
new file mode 100644
index 0000000..de4b813
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.h
@@ -0,0 +1,93 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * pubsub_admin_impl.h
+ *
+ *  \date       Dec 5, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_ADMIN_UDP_MC_IMPL_H_
+#define PUBSUB_ADMIN_UDP_MC_IMPL_H_
+
+#include "pubsub_admin.h"
+#include "log_helper.h"
+
+#define PUBSUB_ADMIN_TYPE	"udp_mc"
+
+struct pubsub_admin {
+
+	bundle_context_pt bundle_context;
+	log_helper_pt loghelper;
+
+	/* List of the available serializers */
+	celix_thread_mutex_t serializerListLock; // List<serializers>
+	array_list_pt serializerList;
+
+	celix_thread_mutex_t localPublicationsLock;
+	hash_map_pt localPublications;//<topic(string),service_factory_pt>
+
+	celix_thread_mutex_t externalPublicationsLock;
+	hash_map_pt externalPublications;//<topic(string),List<pubsub_ep>>
+
+	celix_thread_mutex_t subscriptionsLock;
+	hash_map_pt subscriptions; //<topic(string),topic_subscription>
+
+	celix_thread_mutex_t pendingSubscriptionsLock;
+	celix_thread_mutexattr_t pendingSubscriptionsAttr;
+	hash_map_pt pendingSubscriptions; //<topic(string),List<pubsub_ep>>
+
+	/* Those are used to keep track of valid subscriptions/publications that still have no valid serializer */
+	celix_thread_mutex_t noSerializerPendingsLock;
+	celix_thread_mutexattr_t noSerializerPendingsAttr;
+	array_list_pt noSerializerSubscriptions; // List<pubsub_ep>
+	array_list_pt noSerializerPublications; // List<pubsub_ep>
+
+	celix_thread_mutex_t usedSerializersLock;
+	hash_map_pt topicSubscriptionsPerSerializer; // <serializer,List<topicSubscription>>
+	hash_map_pt topicPublicationsPerSerializer; // <serializer,List<topicPublications>>
+
+	char* ifIpAddress; // The local interface which is used for multicast communication
+	char* mcIpAddress; // The multicast IP address
+
+	int sendSocket;
+	void* zmq_context; // to be removed
+
+};
+
+celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin);
+celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin);
+
+celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+
+celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
+celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
+
+celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char* scope, char* topic);
+celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char* scope, char* topic);
+
+celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service);
+
+celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score);
+
+
+#endif /* PUBSUB_ADMIN_UDP_MC_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_publication.c b/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
new file mode 100644
index 0000000..e43ec29
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
@@ -0,0 +1,444 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  htPSA_UDP_MC_TP://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * topic_publication.c
+ *
+ *  \date       Sep 24, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "array_list.h"
+#include "celixbool.h"
+#include "service_registration.h"
+#include "utils.h"
+#include "service_factory.h"
+#include "version.h"
+
+#include "topic_publication.h"
+#include "pubsub_common.h"
+#include "publisher.h"
+#include "large_udp.h"
+
+#include "pubsub_serializer.h"
+
+#define EP_ADDRESS_LEN		32
+
+#define FIRST_SEND_DELAY	2
+
+struct topic_publication {
+	int sendSocket;
+	char* endpoint;
+	service_registration_pt svcFactoryReg;
+	array_list_pt pub_ep_list; //List<pubsub_endpoint>
+	hash_map_pt boundServices; //<bundle_pt,bound_service>
+	celix_thread_mutex_t tp_lock;
+	pubsub_serializer_service_t *serializer;
+	struct sockaddr_in destAddr;
+};
+
+typedef struct publish_bundle_bound_service {
+	topic_publication_pt parent;
+	pubsub_publisher_t service;
+	bundle_pt bundle;
+	char *scope;
+	char *topic;
+	hash_map_pt msgTypes;
+	unsigned short getCount;
+	celix_thread_mutex_t mp_lock;
+	largeUdp_pt largeUdpHandle;
+}* publish_bundle_bound_service_pt;
+
+
+typedef struct pubsub_msg{
+	pubsub_msg_header_pt header;
+	char* payload;
+	unsigned int payloadSize;
+} pubsub_msg_t;
+
+
+static unsigned int rand_range(unsigned int min, unsigned int max);
+
+static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
+static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
+
+static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle);
+static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc);
+
+static int pubsub_topicPublicationSend(void* handle,unsigned int msgTypeId, const void *msg);
+
+static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId);
+
+
+static void delay_first_send_for_late_joiners(void);
+
+
+celix_status_t pubsub_topicPublicationCreate(int sendSocket, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, topic_publication_pt *out){
+
+	char* ep = malloc(EP_ADDRESS_LEN);
+	memset(ep,0,EP_ADDRESS_LEN);
+	unsigned int port = pubEP->serviceID + rand_range(UDP_BASE_PORT+pubEP->serviceID+3, UDP_MAX_PORT);
+	snprintf(ep,EP_ADDRESS_LEN,"udp://%s:%u",bindIP,port);
+
+
+	topic_publication_pt pub = calloc(1,sizeof(*pub));
+
+	arrayList_create(&(pub->pub_ep_list));
+	pub->boundServices = hashMap_create(NULL,NULL,NULL,NULL);
+	celixThreadMutex_create(&(pub->tp_lock),NULL);
+
+	pub->endpoint = ep;
+	pub->sendSocket = sendSocket;
+	pub->destAddr.sin_family = AF_INET;
+	pub->destAddr.sin_addr.s_addr = inet_addr(bindIP);
+	pub->destAddr.sin_port = htons(port);
+
+	pub->serializer = best_serializer;
+
+	pubsub_topicPublicationAddPublisherEP(pub,pubEP);
+
+	*out = pub;
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&(pub->tp_lock));
+
+	free(pub->endpoint);
+	arrayList_destroy(pub->pub_ep_list);
+
+	hash_map_iterator_pt iter = hashMapIterator_create(pub->boundServices);
+	while(hashMapIterator_hasNext(iter)){
+		publish_bundle_bound_service_pt bound = hashMapIterator_nextValue(iter);
+		pubsub_destroyPublishBundleBoundService(bound);
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(pub->boundServices,false,false);
+
+	pub->svcFactoryReg = NULL;
+	pub->serializer = NULL;
+
+	if(close(pub->sendSocket) != 0){
+		status = CELIX_FILE_IO_EXCEPTION;
+	}
+
+	celixThreadMutex_unlock(&(pub->tp_lock));
+
+	celixThreadMutex_destroy(&(pub->tp_lock));
+
+	free(pub);
+
+	return status;
+}
+
+celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory){
+	celix_status_t status = CELIX_SUCCESS;
+
+	/* Let's register the new service */
+
+	pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pub->pub_ep_list,0);
+
+	if(pubEP!=NULL){
+		service_factory_pt factory = calloc(1, sizeof(*factory));
+		factory->handle = pub;
+		factory->getService = pubsub_topicPublicationGetService;
+		factory->ungetService = pubsub_topicPublicationUngetService;
+
+		properties_pt props = properties_create();
+		properties_set(props,PUBSUB_PUBLISHER_SCOPE,pubEP->scope);
+		properties_set(props,PUBSUB_PUBLISHER_TOPIC,pubEP->topic);
+
+		status = bundleContext_registerServiceFactory(bundle_context,PUBSUB_PUBLISHER_SERVICE_NAME,factory,props,&(pub->svcFactoryReg));
+
+		if(status != CELIX_SUCCESS){
+			properties_destroy(props);
+			printf("PSA_UDP_MC_PSA_UDP_MC_TP: Cannot register ServiceFactory for topic %s, topic %s (bundle %ld).\n",pubEP->scope, pubEP->topic,pubEP->serviceID);
+		}
+		else{
+			*svcFactory = factory;
+		}
+	}
+	else{
+		printf("PSA_UDP_MC_PSA_UDP_MC_TP: Cannot find pubsub_endpoint after adding it...Should never happen!\n");
+		status = CELIX_SERVICE_EXCEPTION;
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub){
+	return serviceRegistration_unregister(pub->svcFactoryReg);
+}
+
+celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
+
+	celixThreadMutex_lock(&(pub->tp_lock));
+	ep->endpoint = strdup(pub->endpoint);
+	arrayList_add(pub->pub_ep_list,ep);
+	celixThreadMutex_unlock(&(pub->tp_lock));
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
+
+	celixThreadMutex_lock(&(pub->tp_lock));
+	arrayList_removeElement(pub->pub_ep_list,ep);
+	celixThreadMutex_unlock(&(pub->tp_lock));
+
+	return CELIX_SUCCESS;
+}
+
+array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub){
+	array_list_pt list = NULL;
+	celixThreadMutex_lock(&(pub->tp_lock));
+	list = arrayList_clone(pub->pub_ep_list);
+	celixThreadMutex_unlock(&(pub->tp_lock));
+	return list;
+}
+
+
+static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service) {
+	celix_status_t  status = CELIX_SUCCESS;
+
+	topic_publication_pt publish = (topic_publication_pt)handle;
+
+	celixThreadMutex_lock(&(publish->tp_lock));
+
+	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
+	if(bound==NULL){
+		bound = pubsub_createPublishBundleBoundService(publish,bundle);
+		if(bound!=NULL){
+			hashMap_put(publish->boundServices,bundle,bound);
+		}
+	}
+	else{
+		bound->getCount++;
+	}
+
+	if (bound != NULL) {
+		*service = &bound->service;
+	}
+
+	celixThreadMutex_unlock(&(publish->tp_lock));
+
+	return status;
+}
+
+static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service)  {
+
+	topic_publication_pt publish = (topic_publication_pt)handle;
+
+	celixThreadMutex_lock(&(publish->tp_lock));
+
+	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
+	if(bound!=NULL){
+
+		bound->getCount--;
+		if(bound->getCount==0){
+			pubsub_destroyPublishBundleBoundService(bound);
+			hashMap_remove(publish->boundServices,bundle);
+		}
+
+	}
+	else{
+		long bundleId = -1;
+		bundle_getBundleId(bundle,&bundleId);
+		printf("PSA_UDP_MC_TP: Unexpected ungetService call for bundle %ld.\n", bundleId);
+	}
+
+	/* service should be never used for unget, so let's set the pointer to NULL */
+	*service = NULL;
+
+	celixThreadMutex_unlock(&(publish->tp_lock));
+
+	return CELIX_SUCCESS;
+}
+
+static bool send_pubsub_msg(publish_bundle_bound_service_pt bound, pubsub_msg_t* msg, bool last, pubsub_release_callback_t *releaseCallback){
+	const int iovec_len = 3; // header + size + payload
+	bool ret = true;
+
+	struct iovec msg_iovec[iovec_len];
+	msg_iovec[0].iov_base = msg->header;
+	msg_iovec[0].iov_len = sizeof(*msg->header);
+	msg_iovec[1].iov_base = &msg->payloadSize;
+	msg_iovec[1].iov_len = sizeof(msg->payloadSize);
+	msg_iovec[2].iov_base = msg->payload;
+	msg_iovec[2].iov_len = msg->payloadSize;
+
+	delay_first_send_for_late_joiners();
+
+	if(largeUdp_sendmsg(bound->largeUdpHandle, bound->parent->sendSocket, msg_iovec, iovec_len, 0, &bound->parent->destAddr, sizeof(bound->parent->destAddr)) == -1) {
+		perror("send_pubsub_msg:sendSocket");
+		ret = false;
+	}
+
+	if(releaseCallback) {
+		releaseCallback->release(msg->payload, bound);
+	}
+	return ret;
+
+}
+
+
+static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *inMsg) {
+	int status = 0;
+	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt) handle;
+
+	celixThreadMutex_lock(&(bound->parent->tp_lock));
+	celixThreadMutex_lock(&(bound->mp_lock));
+
+	pubsub_msg_serializer_t* msgSer = (pubsub_msg_serializer_t*)hashMap_get(bound->msgTypes, (void*)(uintptr_t)msgTypeId);
+
+	if (msgSer != NULL) {
+		int major=0, minor=0;
+
+		pubsub_msg_header_pt msg_hdr = calloc(1,sizeof(struct pubsub_msg_header));
+		strncpy(msg_hdr->topic,bound->topic,MAX_TOPIC_LEN-1);
+		msg_hdr->type = msgTypeId;
+
+
+		if (msgSer->msgVersion != NULL){
+			version_getMajor(msgSer->msgVersion, &major);
+			version_getMinor(msgSer->msgVersion, &minor);
+			msg_hdr->major = major;
+			msg_hdr->minor = minor;
+		}
+
+		void* serializedOutput = NULL;
+		size_t serializedOutputLen = 0;
+		msgSer->serialize(msgSer,inMsg,&serializedOutput, &serializedOutputLen);
+
+		pubsub_msg_t *msg = calloc(1,sizeof(pubsub_msg_t));
+		msg->header = msg_hdr;
+		msg->payload = (char*)serializedOutput;
+		msg->payloadSize = serializedOutputLen;
+
+
+		if(send_pubsub_msg(bound, msg,true, NULL) == false) {
+			status = -1;
+		}
+		free(msg_hdr);
+		free(msg);
+		free(serializedOutput);
+
+
+	} else {
+		printf("PSA_UDP_MC_TP: No msg serializer available for msg type id %d\n", msgTypeId);
+		status=-1;
+	}
+
+	celixThreadMutex_unlock(&(bound->mp_lock));
+	celixThreadMutex_unlock(&(bound->parent->tp_lock));
+
+	return status;
+}
+
+static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId){
+	*msgTypeId = utils_stringHash(msgType);
+	return 0;
+}
+
+
+static unsigned int rand_range(unsigned int min, unsigned int max){
+
+	double scaled = (double)(((double)random())/((double)RAND_MAX));
+	return (max-min+1)*scaled + min;
+
+}
+
+static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle){
+
+	publish_bundle_bound_service_pt bound = calloc(1, sizeof(*bound));
+
+	if (bound != NULL) {
+
+		bound->parent = tp;
+		bound->bundle = bundle;
+		bound->getCount = 1;
+		celixThreadMutex_create(&bound->mp_lock,NULL);
+
+		if(tp->serializer != NULL){
+			tp->serializer->createSerializerMap(tp->serializer->handle,bundle,&bound->msgTypes);
+		}
+
+		pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(bound->parent->pub_ep_list,0);
+		bound->scope=strdup(pubEP->scope);
+		bound->topic=strdup(pubEP->topic);
+		bound->largeUdpHandle = largeUdp_create(1);
+
+		bound->service.handle = bound;
+		bound->service.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForUUID;
+		bound->service.send = pubsub_topicPublicationSend;
+		bound->service.sendMultipart = NULL;  //Multipart not supported for UDP
+
+	}
+
+	return bound;
+}
+
+static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc){
+
+	celixThreadMutex_lock(&boundSvc->mp_lock);
+
+	if(boundSvc->parent->serializer != NULL && boundSvc->msgTypes != NULL){
+		boundSvc->parent->serializer->destroySerializerMap(boundSvc->parent->serializer->handle, boundSvc->msgTypes);
+	}
+
+	if(boundSvc->scope!=NULL){
+		free(boundSvc->scope);
+	}
+
+	if(boundSvc->topic!=NULL){
+		free(boundSvc->topic);
+	}
+
+	largeUdp_destroy(boundSvc->largeUdpHandle);
+
+	celixThreadMutex_unlock(&boundSvc->mp_lock);
+	celixThreadMutex_destroy(&boundSvc->mp_lock);
+
+	free(boundSvc);
+
+}
+
+static void delay_first_send_for_late_joiners(){
+
+	static bool firstSend = true;
+
+	if(firstSend){
+		printf("PSA_UDP_MC_TP: Delaying first send for late joiners...\n");
+		sleep(FIRST_SEND_DELAY);
+		firstSend = false;
+	}
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_publication.h b/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
new file mode 100644
index 0000000..4363d71
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
@@ -0,0 +1,57 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * topic_publication.h
+ *
+ *  \date       Sep 24, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef TOPIC_PUBLICATION_H_
+#define TOPIC_PUBLICATION_H_
+
+#include "publisher.h"
+#include "pubsub_endpoint.h"
+#include "pubsub_common.h"
+
+#include "pubsub_serializer.h"
+
+#define UDP_BASE_PORT	49152
+#define UDP_MAX_PORT	65000
+
+typedef struct pubsub_udp_msg {
+    struct pubsub_msg_header header;
+    unsigned int payloadSize;
+    char payload[];
+} pubsub_udp_msg_t;
+
+typedef struct topic_publication *topic_publication_pt;
+celix_status_t pubsub_topicPublicationCreate(int sendSocket, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, topic_publication_pt *out);
+celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub);
+
+celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
+celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
+
+celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory);
+celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub);
+
+array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub);
+
+#endif /* TOPIC_PUBLICATION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
new file mode 100644
index 0000000..d8e6f45
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
@@ -0,0 +1,635 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * topic_subscription.c
+ *
+ *  \date       Oct 2, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "utils.h"
+#include "celix_errno.h"
+#include "constants.h"
+#include "version.h"
+
+#include "topic_subscription.h"
+#include "topic_publication.h"
+#include "subscriber.h"
+#include "publisher.h"
+#include "large_udp.h"
+
+#include "pubsub_serializer.h"
+
+#define MAX_EPOLL_EVENTS        10
+#define RECV_THREAD_TIMEOUT     5
+#define UDP_BUFFER_SIZE         65535
+#define MAX_UDP_SESSIONS        16
+
+struct topic_subscription{
+	char* ifIpAddress;
+	service_tracker_pt tracker;
+	array_list_pt sub_ep_list;
+	celix_thread_t recv_thread;
+	bool running;
+	celix_thread_mutex_t ts_lock;
+	bundle_context_pt context;
+
+	pubsub_serializer_service_t *serializer;
+
+	int topicEpollFd; // EPOLL filedescriptor where the sockets are registered.
+	hash_map_pt servicesMap; // key = service, value = msg types map
+	hash_map_pt socketMap; // key = URL, value = listen-socket
+	celix_thread_mutex_t socketMap_lock;
+
+	celix_thread_mutex_t pendingConnections_lock;
+	array_list_pt pendingConnections;
+
+	array_list_pt pendingDisconnections;
+	celix_thread_mutex_t pendingDisconnections_lock;
+
+	//array_list_pt rawServices;
+	unsigned int nrSubscribers;
+	largeUdp_pt largeUdpHandle;
+};
+
+typedef struct msg_map_entry{
+	bool retain;
+	void* msgInst;
+}* msg_map_entry_pt;
+
+static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service);
+static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service);
+static void* udp_recv_thread_func(void* arg);
+static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr);
+static void sigusr1_sighandler(int signo);
+static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId);
+static void connectPendingPublishers(topic_subscription_pt sub);
+static void disconnectPendingPublishers(topic_subscription_pt sub);
+
+
+celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* ifIp,char* scope, char* topic ,pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out){
+	celix_status_t status = CELIX_SUCCESS;
+
+	topic_subscription_pt ts = (topic_subscription_pt) calloc(1,sizeof(*ts));
+	ts->context = bundle_context;
+	ts->ifIpAddress = strdup(ifIp);
+#if defined(__APPLE__) && defined(__MACH__)
+	//TODO: Use kqueue for OSX
+#else
+	ts->topicEpollFd = epoll_create1(0);
+#endif
+	if(ts->topicEpollFd == -1) {
+		status += CELIX_SERVICE_EXCEPTION;
+	}
+
+	ts->running = false;
+	ts->nrSubscribers = 0;
+	ts->serializer = best_serializer;
+
+	celixThreadMutex_create(&ts->ts_lock,NULL);
+	arrayList_create(&ts->sub_ep_list);
+	ts->servicesMap = hashMap_create(NULL, NULL, NULL, NULL);
+	ts->socketMap =  hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+	arrayList_create(&ts->pendingConnections);
+	arrayList_create(&ts->pendingDisconnections);
+	celixThreadMutex_create(&ts->pendingConnections_lock, NULL);
+	celixThreadMutex_create(&ts->pendingDisconnections_lock, NULL);
+	celixThreadMutex_create(&ts->socketMap_lock, NULL);
+
+	ts->largeUdpHandle = largeUdp_create(MAX_UDP_SESSIONS);
+
+	char filter[128];
+	memset(filter,0,128);
+	if(strncmp(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, scope, strlen(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT)) == 0) {
+		// default scope, means that subscriber has not defined a scope property
+		snprintf(filter, 128, "(&(%s=%s)(%s=%s))",
+				(char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
+				PUBSUB_SUBSCRIBER_TOPIC,topic);
+
+	} else {
+		snprintf(filter, 128, "(&(%s=%s)(%s=%s)(%s=%s))",
+				(char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
+				PUBSUB_SUBSCRIBER_TOPIC,topic,
+				PUBSUB_SUBSCRIBER_SCOPE,scope);
+	}
+
+	service_tracker_customizer_pt customizer = NULL;
+	status += serviceTrackerCustomizer_create(ts,NULL,topicsub_subscriberTracked,NULL,topicsub_subscriberUntracked,&customizer);
+	status += serviceTracker_createWithFilter(bundle_context, filter, customizer, &ts->tracker);
+
+	struct sigaction actions;
+	memset(&actions, 0, sizeof(actions));
+	sigemptyset(&actions.sa_mask);
+	actions.sa_flags = 0;
+	actions.sa_handler = sigusr1_sighandler;
+
+	sigaction(SIGUSR1,&actions,NULL);
+
+	if (status == CELIX_SUCCESS) {
+		*out=ts;
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	ts->running = false;
+	free(ts->ifIpAddress);
+	serviceTracker_destroy(ts->tracker);
+	arrayList_clear(ts->sub_ep_list);
+	arrayList_destroy(ts->sub_ep_list);
+	hashMap_destroy(ts->servicesMap,false,false);
+
+	celixThreadMutex_lock(&ts->socketMap_lock);
+	hashMap_destroy(ts->socketMap,true,true);
+	celixThreadMutex_unlock(&ts->socketMap_lock);
+	celixThreadMutex_destroy(&ts->socketMap_lock);
+
+	celixThreadMutex_lock(&ts->pendingConnections_lock);
+	arrayList_destroy(ts->pendingConnections);
+	celixThreadMutex_unlock(&ts->pendingConnections_lock);
+	celixThreadMutex_destroy(&ts->pendingConnections_lock);
+
+	celixThreadMutex_lock(&ts->pendingDisconnections_lock);
+	arrayList_destroy(ts->pendingDisconnections);
+	celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
+	celixThreadMutex_destroy(&ts->pendingDisconnections_lock);
+
+	largeUdp_destroy(ts->largeUdpHandle);
+#if defined(__APPLE__) && defined(__MACH__)
+	//TODO: Use kqueue for OSX
+#else
+	close(ts->topicEpollFd);
+#endif
+
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	celixThreadMutex_destroy(&ts->ts_lock);
+
+	free(ts);
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts){
+	celix_status_t status = CELIX_SUCCESS;
+
+	status = serviceTracker_open(ts->tracker);
+
+	ts->running = true;
+
+	if(status==CELIX_SUCCESS){
+		status=celixThread_create(&ts->recv_thread,NULL,udp_recv_thread_func,ts);
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts){
+	celix_status_t status = CELIX_SUCCESS;
+	struct epoll_event ev;
+	memset(&ev, 0, sizeof(ev));
+
+	ts->running = false;
+
+	pthread_kill(ts->recv_thread.thread,SIGUSR1);
+
+	celixThread_join(ts->recv_thread,NULL);
+
+	status = serviceTracker_close(ts->tracker);
+
+	celixThreadMutex_lock(&ts->socketMap_lock);
+	hash_map_iterator_pt it = hashMapIterator_create(ts->socketMap);
+	while(hashMapIterator_hasNext(it)) {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(it);
+		char *url = hashMapEntry_getKey(entry);
+		int *s = hashMapEntry_getValue(entry);
+		memset(&ev, 0, sizeof(ev));
+		if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_DEL, *s, &ev) == -1) {
+			printf("in if error()\n");
+			perror("epoll_ctl() EPOLL_CTL_DEL");
+			status += CELIX_SERVICE_EXCEPTION;
+		}
+		free(s);
+		free(url);
+		//hashMapIterator_remove(it);
+	}
+	hashMapIterator_destroy(it);
+	hashMap_clear(ts->socketMap, false, false);
+	celixThreadMutex_unlock(&ts->socketMap_lock);
+
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL) {
+
+	printf("pubsub_topicSubscriptionConnectPublisher : pubURL = %s\n", pubURL);
+
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->socketMap_lock);
+
+	if(!hashMap_containsKey(ts->socketMap, pubURL)){
+
+		int *recvSocket = calloc(sizeof(int), 1);
+		*recvSocket = socket(AF_INET, SOCK_DGRAM, 0);
+		if (*recvSocket < 0) {
+			perror("pubsub_topicSubscriptionCreate:socket");
+			status = CELIX_SERVICE_EXCEPTION;
+		}
+
+		if (status == CELIX_SUCCESS){
+			int reuse = 1;
+			if (setsockopt(*recvSocket, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) != 0) {
+				perror("setsockopt() SO_REUSEADDR");
+				status = CELIX_SERVICE_EXCEPTION;
+			}
+		}
+
+		if(status == CELIX_SUCCESS){
+			// TODO Check if there is a better way to parse the URL to IP/Portnr
+			//replace ':' by spaces
+			char *url = strdup(pubURL);
+			char *pt = url;
+			while((pt=strchr(pt, ':')) != NULL) {
+				*pt = ' ';
+			}
+			char mcIp[100];
+			unsigned short mcPort;
+			sscanf(url, "udp //%s %hu", mcIp, &mcPort);
+			free(url);
+
+			printf("pubsub_topicSubscriptionConnectPublisher : IP = %s, Port = %hu\n", mcIp, mcPort);
+
+			struct ip_mreq mc_addr;
+			mc_addr.imr_multiaddr.s_addr = inet_addr(mcIp);
+			mc_addr.imr_interface.s_addr = inet_addr(ts->ifIpAddress);
+			printf("Adding MC %s at interface %s\n", mcIp, ts->ifIpAddress);
+			if (setsockopt(*recvSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mc_addr, sizeof(mc_addr)) != 0) {
+				perror("setsockopt() IP_ADD_MEMBERSHIP");
+				status = CELIX_SERVICE_EXCEPTION;
+			}
+
+			if (status == CELIX_SUCCESS){
+				struct sockaddr_in mcListenAddr;
+				mcListenAddr.sin_family = AF_INET;
+				mcListenAddr.sin_addr.s_addr = INADDR_ANY;
+				mcListenAddr.sin_port = htons(mcPort);
+				if(bind(*recvSocket, (struct sockaddr*)&mcListenAddr, sizeof(mcListenAddr)) != 0) {
+					perror("bind()");
+					status = CELIX_SERVICE_EXCEPTION;
+				}
+			}
+
+			if (status == CELIX_SUCCESS){
+#if defined(__APPLE__) && defined(__MACH__)
+				//TODO: Use kqueue for OSX
+#else
+				struct epoll_event ev;
+				memset(&ev, 0, sizeof(ev));
+				ev.events = EPOLLIN;
+				ev.data.fd = *recvSocket;
+				if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_ADD, *recvSocket, &ev) == -1) {
+					perror("epoll_ctl() EPOLL_CTL_ADD");
+					status = CELIX_SERVICE_EXCEPTION;
+				}
+#endif
+			}
+
+		}
+
+		if (status == CELIX_SUCCESS){
+			hashMap_put(ts->socketMap, strdup(pubURL), (void*)recvSocket);
+		}
+		else{
+			free(recvSocket);
+		}
+	}
+
+	celixThreadMutex_unlock(&ts->socketMap_lock);
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
+	celix_status_t status = CELIX_SUCCESS;
+	char *url = strdup(pubURL);
+	celixThreadMutex_lock(&ts->pendingConnections_lock);
+	arrayList_add(ts->pendingConnections, url);
+	celixThreadMutex_unlock(&ts->pendingConnections_lock);
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
+	celix_status_t status = CELIX_SUCCESS;
+	char *url = strdup(pubURL);
+	celixThreadMutex_lock(&ts->pendingDisconnections_lock);
+	arrayList_add(ts->pendingDisconnections, url);
+	celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL){
+	printf("pubsub_topicSubscriptionDisconnectPublisher : pubURL = %s\n", pubURL);
+	celix_status_t status = CELIX_SUCCESS;
+	struct epoll_event ev;
+	memset(&ev, 0, sizeof(ev));
+
+	celixThreadMutex_lock(&ts->socketMap_lock);
+
+	if (hashMap_containsKey(ts->socketMap, pubURL)){
+
+#if defined(__APPLE__) && defined(__MACH__)
+		//TODO: Use kqueue for OSX
+#else
+		int *s = hashMap_remove(ts->socketMap, pubURL);
+		if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_DEL, *s, &ev) == -1) {
+			printf("in if error()\n");
+			perror("epoll_ctl() EPOLL_CTL_DEL");
+			status = CELIX_SERVICE_EXCEPTION;
+		}
+		free(s);
+#endif
+
+	}
+
+	celixThreadMutex_unlock(&ts->socketMap_lock);
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	arrayList_add(ts->sub_ep_list,subEP);
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+
+}
+
+celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt ts) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	ts->nrSubscribers++;
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	arrayList_removeElement(ts->sub_ep_list,subEP);
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+}
+
+celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt ts) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	ts->nrSubscribers--;
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+}
+
+unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt ts) {
+	return ts->nrSubscribers;
+}
+
+array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub){
+	return sub->sub_ep_list;
+}
+
+
+static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service){
+	celix_status_t status = CELIX_SUCCESS;
+	topic_subscription_pt ts = handle;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	if (!hashMap_containsKey(ts->servicesMap, service)) {
+		bundle_pt bundle = NULL;
+		hash_map_pt msgTypes = NULL;
+
+		serviceReference_getBundle(reference, &bundle);
+
+		if(ts->serializer != NULL && bundle!=NULL){
+			ts->serializer->createSerializerMap(ts->serializer->handle,bundle,&msgTypes);
+			if(msgTypes != NULL){
+				hashMap_put(ts->servicesMap, service, msgTypes);
+				printf("PSA_UDP_MC_TS: New subscriber registered.\n");
+			}
+		}
+		else{
+			printf("PSA_UDP_MC_TS: Cannot register new subscriber.\n");
+			status = CELIX_SERVICE_EXCEPTION;
+		}
+	}
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+
+}
+
+static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service){
+	celix_status_t status = CELIX_SUCCESS;
+	topic_subscription_pt ts = handle;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	if (hashMap_containsKey(ts->servicesMap, service)) {
+		hash_map_pt msgTypes = hashMap_remove(ts->servicesMap, service);
+		if(msgTypes!=NULL && ts->serializer!=NULL){
+			ts->serializer->destroySerializerMap(ts->serializer->handle,msgTypes);
+			printf("PSA_ZMQ_TS: Subscriber unregistered.\n");
+		}
+		else{
+			printf("PSA_ZMQ_TS: Cannot unregister subscriber.\n");
+			status = CELIX_SERVICE_EXCEPTION;
+		}
+	}
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	printf("PSA_UDP_MC_TS: Subscriber unregistered.\n");
+	return status;
+}
+
+
+static void process_msg(topic_subscription_pt sub,pubsub_udp_msg_t *msg){
+
+	celixThreadMutex_lock(&sub->ts_lock);
+	hash_map_iterator_pt iter = hashMapIterator_create(sub->servicesMap);
+	while (hashMapIterator_hasNext(iter)) {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		pubsub_subscriber_pt subsvc = hashMapEntry_getKey(entry);
+		hash_map_pt msgTypes = hashMapEntry_getValue(entry);
+
+		pubsub_msg_serializer_t *msgSer = hashMap_get(msgTypes,(void*)(uintptr_t )msg->header.type);
+		if (msgSer == NULL) {
+			printf("PSA_UDP_MC_TS: Serializer not available for message %d.\n",msg->header.type);
+		}
+		else{
+			void *msgInst = NULL;
+			bool validVersion = checkVersion(msgSer->msgVersion,&msg->header);
+
+			if(validVersion){
+
+				celix_status_t status = msgSer->deserialize(msgSer, (const void *) msg->payload, 0, &msgInst);
+
+				if (status == CELIX_SUCCESS) {
+					bool release = true;
+					pubsub_multipart_callbacks_t mp_callbacks;
+					mp_callbacks.handle = sub;
+					mp_callbacks.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForMsgType;
+					mp_callbacks.getMultipart = NULL;
+
+					subsvc->receive(subsvc->handle, msgSer->msgName, msg->header.type, msgInst, &mp_callbacks, &release);
+
+					if(release){
+						msgSer->freeMsg(msgSer,msgInst);
+					}
+				}
+				else{
+					printf("PSA_UDP_MC_TS: Cannot deserialize msgType %s.\n",msgSer->msgName);
+				}
+
+			}
+			else{
+				int major=0,minor=0;
+				version_getMajor(msgSer->msgVersion,&major);
+				version_getMinor(msgSer->msgVersion,&minor);
+				printf("PSA_UDP_MC_TS: Version mismatch for primary message '%s' (have %d.%d, received %u.%u). NOT sending any part of the whole message.\n",
+						msgSer->msgName,major,minor,msg->header.major,msg->header.minor);
+			}
+
+		}
+	}
+	hashMapIterator_destroy(iter);
+	celixThreadMutex_unlock(&sub->ts_lock);
+}
+
+static void* udp_recv_thread_func(void * arg) {
+	topic_subscription_pt sub = (topic_subscription_pt) arg;
+
+#if defined(__APPLE__) && defined(__MACH__)
+	//TODO: use kqueue for OSX
+	//struct kevent events[MAX_EPOLL_EVENTS];
+	while (sub->running) {
+		int nfds = 0;
+		if(nfds > 0) {
+			pubsub_udp_msg_t* udpMsg = NULL;
+			process_msg(sub, udpMsg);
+		}
+	}
+#else
+	struct epoll_event events[MAX_EPOLL_EVENTS];
+
+	while (sub->running) {
+		int nfds = epoll_wait(sub->topicEpollFd, events, MAX_EPOLL_EVENTS, RECV_THREAD_TIMEOUT * 1000);
+		int i;
+		for(i = 0; i < nfds; i++ ) {
+			unsigned int index;
+			unsigned int size;
+			if(largeUdp_dataAvailable(sub->largeUdpHandle, events[i].data.fd, &index, &size) == true) {
+				// Handle data
+				pubsub_udp_msg_t *udpMsg = NULL;
+				if(largeUdp_read(sub->largeUdpHandle, index, (void**)&udpMsg, size) != 0) {
+					printf("PSA_UDP_MC_TS: ERROR largeUdp_read with index %d\n", index);
+					continue;
+				}
+
+				process_msg(sub, udpMsg);
+
+				free(udpMsg);
+			}
+		}
+		connectPendingPublishers(sub);
+		disconnectPendingPublishers(sub);
+	}
+#endif
+
+	return NULL;
+}
+
+static void connectPendingPublishers(topic_subscription_pt sub) {
+	celixThreadMutex_lock(&sub->pendingConnections_lock);
+	while(!arrayList_isEmpty(sub->pendingConnections)) {
+		char * pubEP = arrayList_remove(sub->pendingConnections, 0);
+		pubsub_topicSubscriptionConnectPublisher(sub, pubEP);
+		free(pubEP);
+	}
+	celixThreadMutex_unlock(&sub->pendingConnections_lock);
+}
+
+static void disconnectPendingPublishers(topic_subscription_pt sub) {
+	celixThreadMutex_lock(&sub->pendingDisconnections_lock);
+	while(!arrayList_isEmpty(sub->pendingDisconnections)) {
+		char * pubEP = arrayList_remove(sub->pendingDisconnections, 0);
+		pubsub_topicSubscriptionDisconnectPublisher(sub, pubEP);
+		free(pubEP);
+	}
+	celixThreadMutex_unlock(&sub->pendingDisconnections_lock);
+}
+
+static void sigusr1_sighandler(int signo){
+	printf("PSA_UDP_MC_TS: Topic subscription being shut down...\n");
+	return;
+}
+
+static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr){
+	bool check=false;
+	int major=0,minor=0;
+
+	if(msgVersion!=NULL){
+		version_getMajor(msgVersion,&major);
+		version_getMinor(msgVersion,&minor);
+		if(hdr->major==((unsigned char)major)){ /* Different major means incompatible */
+			check = (hdr->minor>=((unsigned char)minor)); /* Compatible only if the provider has a minor equals or greater (means compatible update) */
+		}
+	}
+
+	return check;
+}
+
+static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId){
+	*msgTypeId = utils_stringHash(msgType);
+	return 0;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/topic_subscription.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_subscription.h b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.h
new file mode 100644
index 0000000..475416a
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.h
@@ -0,0 +1,60 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * topic_subscription.h
+ *
+ *  \date       Sep 22, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef TOPIC_SUBSCRIPTION_H_
+#define TOPIC_SUBSCRIPTION_H_
+
+#include "celix_threads.h"
+#include "array_list.h"
+#include "celixbool.h"
+#include "service_tracker.h"
+
+#include "pubsub_endpoint.h"
+#include "pubsub_common.h"
+#include "pubsub_serializer.h"
+
+typedef struct topic_subscription* topic_subscription_pt;
+
+celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* ifIp,char* scope, char* topic ,pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out);
+celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts);
+celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts);
+celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts);
+
+celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
+celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
+
+celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL);
+celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL);
+
+celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
+celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
+
+array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub);
+celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt subscription);
+celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt subscription);
+unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt subscription);
+
+#endif /*TOPIC_SUBSCRIPTION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_zmq/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/CMakeLists.txt b/pubsub/pubsub_admin_zmq/CMakeLists.txt
index ab250f9..d71aedb 100644
--- a/pubsub/pubsub_admin_zmq/CMakeLists.txt
+++ b/pubsub/pubsub_admin_zmq/CMakeLists.txt
@@ -50,14 +50,15 @@ if (BUILD_PUBSUB_PSA_ZMQ)
 	    	private/src/topic_subscription.c
 	    	private/src/topic_publication.c
 	    	${ZMQ_CRYPTO_C}
-	    	${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
 	    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
 	    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
     	   ${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_admin_match.c
 	)
 
 	set_target_properties(org.apache.celix.pubsub_admin.PubSubAdminZmq PROPERTIES INSTALL_RPATH "$ORIGIN")
-	target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminZmq celix_framework celix_utils celix_dfi ${ZMQ_LIBRARIES} ${CZMQ_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARY})
+	target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminZmq PRIVATE
+			Celix::framework Celix::dfi Celix::log_helper
+			${ZMQ_LIBRARIES} ${CZMQ_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARY})
 	install_bundle(org.apache.celix.pubsub_admin.PubSubAdminZmq)
 
 endif()


[02/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/utils/private/src/civetweb.c
----------------------------------------------------------------------
diff --git a/remote_services/utils/private/src/civetweb.c b/remote_services/utils/private/src/civetweb.c
deleted file mode 100644
index a6093b7..0000000
--- a/remote_services/utils/private/src/civetweb.c
+++ /dev/null
@@ -1,7907 +0,0 @@
-	/* Copyright (c) 2013-2015 the Civetweb developers
- * Copyright (c) 2004-2013 Sergey Lyubka
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#if defined(_WIN32)
-#if !defined(_CRT_SECURE_NO_WARNINGS)
-#define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */
-#endif
-#else
-#ifdef __linux__
-#define _XOPEN_SOURCE 600     /* For flockfile() on Linux */
-#endif
-#ifndef _LARGEFILE_SOURCE
-#define _LARGEFILE_SOURCE     /* For fseeko(), ftello() */
-#endif
-#ifndef _FILE_OFFSET_BITS
-#define _FILE_OFFSET_BITS 64  /* Use 64-bit file offsets by default */
-#endif
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS  /* <inttypes.h> wants this for C++ */
-#endif
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS   /* C++ wants that for INT64_MAX */
-#endif
-#endif
-
-#if defined (_MSC_VER)
-/* 'type cast' : conversion from 'int' to 'HANDLE' of greater size */
-#pragma warning (disable : 4306 )
-/* conditional expression is constant: introduced by FD_SET(..) */
-#pragma warning (disable : 4127)
-/* non-constant aggregate initializer: issued due to missing C99 support */
-#pragma warning (disable : 4204)
-#endif
-
-/* Disable WIN32_LEAN_AND_MEAN.
-   This makes windows.h always include winsock2.h */
-#if defined(WIN32_LEAN_AND_MEAN)
-#undef WIN32_LEAN_AND_MEAN
-#endif
-
-#if defined USE_IPV6 && defined(_WIN32)
-#include <ws2tcpip.h>
-#endif
-
-#if defined(__SYMBIAN32__)
-#define NO_SSL /* SSL is not supported */
-#define NO_CGI /* CGI is not supported */
-#define PATH_MAX FILENAME_MAX
-#endif /* __SYMBIAN32__ */
-
-#ifndef IGNORE_UNUSED_RESULT
-#define IGNORE_UNUSED_RESULT(a) (void)((a) && 1)
-#endif
-
-#ifndef _WIN32_WCE /* Some ANSI #includes are not available on Windows CE */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <signal.h>
-#include <fcntl.h>
-#endif /* !_WIN32_WCE */
-
-#include <time.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#ifndef MAX_WORKER_THREADS
-#define MAX_WORKER_THREADS (1024*64)
-#endif
-
-#if defined(_WIN32) && !defined(__SYMBIAN32__) /* Windows specific */
-#if defined(_MSC_VER) && _MSC_VER <= 1400
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400 /* To make it link in VS2005 */
-#endif
-#include <windows.h>
-typedef const char * SOCK_OPT_TYPE;
-
-#ifndef PATH_MAX
-#define PATH_MAX MAX_PATH
-#endif
-
-#ifndef _IN_PORT_T
-#ifndef in_port_t
-#define in_port_t u_short
-#endif
-#endif
-
-#ifndef _WIN32_WCE
-#include <process.h>
-#include <direct.h>
-#include <io.h>
-#else /* _WIN32_WCE */
-#define NO_CGI /* WinCE has no pipes */
-
-typedef long off_t;
-
-#define errno   GetLastError()
-#define strerror(x)  _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10)
-#endif /* _WIN32_WCE */
-
-#define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \
-      ((uint64_t)((uint32_t)(hi))) << 32))
-#define RATE_DIFF 10000000 /* 100 nsecs */
-#define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de)
-#define SYS2UNIX_TIME(lo, hi) \
-  (time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)
-
-/* Visual Studio 6 does not know __func__ or __FUNCTION__
-   The rest of MS compilers use __FUNCTION__, not C99 __func__
-   Also use _strtoui64 on modern M$ compilers */
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define STRX(x) #x
-#define STR(x) STRX(x)
-#define __func__ __FILE__ ":" STR(__LINE__)
-#define strtoull(x, y, z) (unsigned __int64) _atoi64(x)
-#define strtoll(x, y, z) _atoi64(x)
-#else
-#define __func__  __FUNCTION__
-#define strtoull(x, y, z) _strtoui64(x, y, z)
-#define strtoll(x, y, z) _strtoi64(x, y, z)
-#endif /* _MSC_VER */
-
-#define ERRNO   GetLastError()
-#define NO_SOCKLEN_T
-#define SSL_LIB   "ssleay32.dll"
-#define CRYPTO_LIB  "libeay32.dll"
-#define O_NONBLOCK  0
-#define W_OK (2) /* http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx */
-#if !defined(EWOULDBLOCK)
-#define EWOULDBLOCK  WSAEWOULDBLOCK
-#endif /* !EWOULDBLOCK */
-#define _POSIX_
-#define INT64_FMT  "I64d"
-
-#define WINCDECL __cdecl
-#define SHUT_WR 1
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#define access _access
-#define mg_sleep(x) Sleep(x)
-
-#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
-#ifndef popen
-#define popen(x, y) _popen(x, y)
-#endif
-#ifndef pclose
-#define pclose(x) _pclose(x)
-#endif
-#define close(x) _close(x)
-#define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y))
-#define RTLD_LAZY  0
-#define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z))
-#define fdopen(x, y) _fdopen((x), (y))
-#define write(x, y, z) _write((x), (y), (unsigned) z)
-#define read(x, y, z) _read((x), (y), (unsigned) z)
-#define flockfile(x) EnterCriticalSection(&global_log_file_lock)
-#define funlockfile(x) LeaveCriticalSection(&global_log_file_lock)
-#define sleep(x) Sleep((x) * 1000)
-#define rmdir(x) _rmdir(x)
-
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
-#define USE_TIMERS
-#endif
-
-#if !defined(va_copy)
-#define va_copy(x, y) x = y
-#endif /* !va_copy MINGW #defines va_copy */
-
-#if !defined(fileno)
-#define fileno(x) _fileno(x)
-#endif /* !fileno MINGW #defines fileno */
-
-typedef HANDLE pthread_mutex_t;
-typedef DWORD pthread_key_t;
-typedef HANDLE pthread_t;
-typedef struct {
-    CRITICAL_SECTION threadIdSec;
-    int waitingthreadcount;        /* The number of threads queued. */
-    pthread_t *waitingthreadhdls;  /* The thread handles. */
-} pthread_cond_t;
-
-#ifndef __clockid_t_defined
-typedef DWORD clockid_t;
-#endif
-#ifndef CLOCK_MONOTONIC
-#define CLOCK_MONOTONIC (1)
-#endif
-#ifndef CLOCK_REALTIME
-#define CLOCK_REALTIME  (2)
-#endif
-
-#ifndef _TIMESPEC_DEFINED
-struct timespec {
-    time_t   tv_sec;        /* seconds */
-    long     tv_nsec;       /* nanoseconds */
-};
-#endif
-
-#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */
-
-static int pthread_mutex_lock(pthread_mutex_t *);
-static int pthread_mutex_unlock(pthread_mutex_t *);
-static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
-struct file;
-static char *mg_fgets(char *buf, size_t size, struct file *filep, char **p);
-
-#if defined(HAVE_STDINT)
-#include <stdint.h>
-#else
-typedef unsigned int  uint32_t;
-typedef unsigned short  uint16_t;
-typedef unsigned __int64 uint64_t;
-typedef __int64   int64_t;
-#define INT64_MAX  9223372036854775807
-#endif /* HAVE_STDINT */
-
-/* POSIX dirent interface */
-struct dirent {
-    char d_name[PATH_MAX];
-};
-
-typedef struct DIR {
-    HANDLE   handle;
-    WIN32_FIND_DATAW info;
-    struct dirent  result;
-} DIR;
-
-#if !defined(USE_IPV6) && defined(_WIN32)
-#ifndef HAVE_POLL
-struct pollfd {
-    SOCKET fd;
-    short events;
-    short revents;
-};
-#define POLLIN 1
-#endif
-#endif
-
-/* Mark required libraries */
-#ifdef _MSC_VER
-#pragma comment(lib, "Ws2_32.lib")
-#endif
-
-#else    /* UNIX  specific */
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <sys/utsname.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <netdb.h>
-typedef const void * SOCK_OPT_TYPE;
-
-//#if defined(ANDROID)
-typedef unsigned short int in_port_t;
-//#endif
-
-#include <pwd.h>
-#include <unistd.h>
-#include <dirent.h>
-#if !defined(NO_SSL_DL) && !defined(NO_SSL)
-#include <dlfcn.h>
-#endif
-#include <pthread.h>
-#if defined(__MACH__)
-#define SSL_LIB   "libssl.dylib"
-#define CRYPTO_LIB  "libcrypto.dylib"
-#else
-#if !defined(SSL_LIB)
-#define SSL_LIB   "libssl.so"
-#endif
-#if !defined(CRYPTO_LIB)
-#define CRYPTO_LIB  "libcrypto.so"
-#endif
-#endif
-#ifndef O_BINARY
-#define O_BINARY  0
-#endif /* O_BINARY */
-#define closesocket(a) close(a)
-#define mg_mkdir(x, y) mkdir(x, y)
-#define mg_remove(x) remove(x)
-#define mg_sleep(x) usleep((x) * 1000)
-#define ERRNO errno
-#define INVALID_SOCKET (-1)
-#define INT64_FMT PRId64
-typedef int SOCKET;
-#define WINCDECL
-
-#endif /* End of Windows and UNIX specific includes */
-
-#ifdef _WIN32
-static CRITICAL_SECTION global_log_file_lock;
-static DWORD pthread_self(void)
-{
-    return GetCurrentThreadId();
-}
-
-int pthread_key_create(pthread_key_t *key, void (*_must_be_zero)(void*) /* destructor function not supported for windows */)
-{
-    assert(_must_be_zero == NULL);
-    if ((key!=0) && (_must_be_zero == NULL)) {
-        *key = TlsAlloc();
-        return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1;
-    }
-    return -2;
-}
-
-int pthread_key_delete(pthread_key_t key)
-{
-    return TlsFree(key) ? 0 : 1;
-}
-
-int pthread_setspecific(pthread_key_t key, void * value)
-{
-    return TlsSetValue(key, value) ? 0 : 1;
-}
-
-void *pthread_getspecific(pthread_key_t key)
-{
-    return TlsGetValue(key);
-}
-#endif /* _WIN32 */
-
-
-#include "civetweb.h"
-
-#define PASSWORDS_FILE_NAME ".htpasswd"
-#define CGI_ENVIRONMENT_SIZE 4096
-#define MAX_CGI_ENVIR_VARS 64
-#define MG_BUF_LEN 8192
-#ifndef MAX_REQUEST_SIZE
-#define MAX_REQUEST_SIZE 16384
-#endif
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-
-#if !defined(DEBUG_TRACE)
-#if defined(CWDEBUG)
-
-static void DEBUG_TRACE_FUNC(const char *func, unsigned line, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(3, 4);
-
-static void DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...) {
-
-  va_list args;
-  flockfile(stdout);
- printf("*** %lu.%p.%s.%u: ",
-         (unsigned long) time(NULL), (void *) pthread_self(),
-         func, line);
-  va_start(args, fmt);
-  vprintf(fmt, args);
-  va_end(args);
-  putchar('\n');
-  fflush(stdout);
-  funlockfile(stdout);
-}
-
-#define DEBUG_TRACE(fmt, ...) DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
-
-#else
-#define DEBUG_TRACE(fmt, ...)
-#endif /* CWDEBUG */
-#endif /* DEBUG_TRACE */
-
-#if defined(MEMORY_DEBUGGING)
-static unsigned long blockCount = 0;
-static unsigned long totalMemUsed = 0;
-
-static void * mg_malloc_ex(size_t size, const char * file, unsigned line) {
-
-    void * data = malloc(size + sizeof(size_t));
-    void * memory = 0;
-    char mallocStr[256];
-
-    if (data) {
-        *(size_t*)data = size;
-        totalMemUsed += size;
-        blockCount++;
-        memory = (void *)(((char*)data)+sizeof(size_t));
-    }
-
-    sprintf(mallocStr, "MEM: %p %5lu alloc   %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
-    OutputDebugStringA(mallocStr);
-#else
-    DEBUG_TRACE("%s", mallocStr);
-#endif
-
-    return memory;
-}
-
-static void * mg_calloc_ex(size_t count, size_t size, const char * file, unsigned line) {
-
-    void * data = mg_malloc_ex(size*count, file, line);
-    if (data) memset(data, 0, size);
-
-    return data;
-}
-
-static void mg_free_ex(void * memory, const char * file, unsigned line) {
-
-    char mallocStr[256];
-    void * data = (void *)(((char*)memory)-sizeof(size_t));
-    size_t size;
-
-    if (memory) {
-        size = *(size_t*)data;
-        totalMemUsed -= size;
-        blockCount--;
-        sprintf(mallocStr, "MEM: %p %5lu free    %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
-        OutputDebugStringA(mallocStr);
-#else
-        DEBUG_TRACE("%s", mallocStr);
-#endif
-
-        free(data);
-    }
-}
-
-static void * mg_realloc_ex(void * memory, size_t newsize, const char * file, unsigned line) {
-
-    char mallocStr[256];
-    void * data;
-    void * _realloc;
-    size_t oldsize;
-
-    if (newsize) {
-        if (memory) {
-            data = (void *)(((char*)memory)-sizeof(size_t));
-            oldsize = *(size_t*)data;
-            _realloc = realloc(data, newsize+sizeof(size_t));
-            if (_realloc) {
-                data = _realloc;
-                totalMemUsed -= oldsize;
-                sprintf(mallocStr, "MEM: %p %5lu r-free  %7lu %4lu --- %s:%u\n", memory, (unsigned long)oldsize, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
-                OutputDebugStringA(mallocStr);
-#else
-                DEBUG_TRACE("%s", mallocStr);
-#endif
-                totalMemUsed += newsize;
-                sprintf(mallocStr, "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)newsize, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
-                OutputDebugStringA(mallocStr);
-#else
-                DEBUG_TRACE("%s", mallocStr);
-#endif
-                *(size_t*)data = newsize;
-                data = (void *)(((char*)data)+sizeof(size_t));
-            } else {
-#if defined(_WIN32)
-                OutputDebugStringA("MEM: realloc failed\n");
-#else
-                DEBUG_TRACE("%s", "MEM: realloc failed\n");
-#endif
-                return _realloc;
-            }
-        } else {
-            data = mg_malloc_ex(newsize, file, line);
-        }
-    } else {
-        data = 0;
-        mg_free_ex(memory, file, line);
-    }
-
-    return data;
-}
-
-#define mg_malloc(a)      mg_malloc_ex(a, __FILE__, __LINE__)
-#define mg_calloc(a,b)    mg_calloc_ex(a, b, __FILE__, __LINE__)
-#define mg_realloc(a, b)  mg_realloc_ex(a, b, __FILE__, __LINE__)
-#define mg_free(a)        mg_free_ex(a, __FILE__, __LINE__)
-
-#else
-static __inline void * mg_malloc(size_t a)             {return malloc(a);}
-static __inline void * mg_calloc(size_t a, size_t b)   {return calloc(a, b);}
-static __inline void * mg_realloc(void * a, size_t b)  {return realloc(a, b);}
-static __inline void   mg_free(void * a)               {free(a);}
-#endif
-
-/* This following lines are just meant as a reminder to use the mg-functions for memory management */
-#ifdef malloc
-    #undef malloc
-#endif
-#ifdef calloc
-    #undef calloc
-#endif
-#ifdef realloc
-    #undef realloc
-#endif
-#ifdef free
-    #undef free
-#endif
-#define malloc  DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc
-#define calloc  DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc
-#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc
-#define free    DO_NOT_USE_THIS_FUNCTION__USE_mg_free
-
-
-#define MD5_STATIC static
-#include "md5.inl"
-
-/* Darwin prior to 7.0 and Win32 do not have socklen_t */
-#ifdef NO_SOCKLEN_T
-typedef int socklen_t;
-#endif /* NO_SOCKLEN_T */
-#define _DARWIN_UNLIMITED_SELECT
-
-#define IP_ADDR_STR_LEN 50  /* IPv6 hex string is 46 chars */
-
-#if !defined(MSG_NOSIGNAL)
-#define MSG_NOSIGNAL 0
-#endif
-
-#if !defined(SOMAXCONN)
-#define SOMAXCONN 100
-#endif
-
-#if !defined(PATH_MAX)
-#define PATH_MAX 4096
-#endif
-
-/* Size of the accepted socket queue */
-#if !defined(MGSQLEN)
-#define MGSQLEN 20
-#endif
-
-#if defined(NO_SSL_DL)
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#else
-/* SSL loaded dynamically from DLL.
-   I put the prototypes here to be independent from OpenSSL source
-   installation. */
-
-typedef struct ssl_st SSL;
-typedef struct ssl_method_st SSL_METHOD;
-typedef struct ssl_ctx_st SSL_CTX;
-
-struct ssl_func {
-    const char *name;   /* SSL function name */
-    void  (*ptr)(void); /* Function pointer */
-};
-
-#define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr)
-#define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr)
-#define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr)
-#define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr)
-#define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr)
-#define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr)
-#define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr)
-#define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
-#define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
-#define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
-#define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr)
-#define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \
-        const char *, int)) ssl_sw[11].ptr)
-#define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \
-        const char *, int)) ssl_sw[12].ptr)
-#define SSL_CTX_set_default_passwd_cb \
-  (* (void (*)(SSL_CTX *, mg_callback_t)) ssl_sw[13].ptr)
-#define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr)
-#define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr)
-#define SSL_CTX_use_certificate_chain_file \
-  (* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr)
-#define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
-#define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr)
-#define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr)
-#define SSL_shutdown (* (int (*)(SSL *)) ssl_sw[20].ptr)
-
-#define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr)
-#define CRYPTO_set_locking_callback \
-  (* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr)
-#define CRYPTO_set_id_callback \
-  (* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr)
-#define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr)
-#define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr)
-
-/* set_ssl_option() function updates this array.
-   It loads SSL library dynamically and changes NULLs to the actual addresses
-   of respective functions. The macros above (like SSL_connect()) are really
-   just calling these functions indirectly via the pointer. */
-static struct ssl_func ssl_sw[] = {
-    {"SSL_free",   NULL},
-    {"SSL_accept",   NULL},
-    {"SSL_connect",   NULL},
-    {"SSL_read",   NULL},
-    {"SSL_write",   NULL},
-    {"SSL_get_error",  NULL},
-    {"SSL_set_fd",   NULL},
-    {"SSL_new",   NULL},
-    {"SSL_CTX_new",   NULL},
-    {"SSLv23_server_method", NULL},
-    {"SSL_library_init",  NULL},
-    {"SSL_CTX_use_PrivateKey_file", NULL},
-    {"SSL_CTX_use_certificate_file",NULL},
-    {"SSL_CTX_set_default_passwd_cb",NULL},
-    {"SSL_CTX_free",  NULL},
-    {"SSL_load_error_strings", NULL},
-    {"SSL_CTX_use_certificate_chain_file", NULL},
-    {"SSLv23_client_method", NULL},
-    {"SSL_pending", NULL},
-    {"SSL_CTX_set_verify", NULL},
-    {"SSL_shutdown",   NULL},
-    {NULL,    NULL}
-};
-
-/* Similar array as ssl_sw. These functions could be located in different
-   lib. */
-#if !defined(NO_SSL)
-static struct ssl_func crypto_sw[] = {
-    {"CRYPTO_num_locks",  NULL},
-    {"CRYPTO_set_locking_callback", NULL},
-    {"CRYPTO_set_id_callback", NULL},
-    {"ERR_get_error",  NULL},
-    {"ERR_error_string", NULL},
-    {NULL,    NULL}
-};
-#endif /* NO_SSL */
-#endif /* NO_SSL_DL */
-
-static const char *month_names[] = {
-    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-/* Unified socket address. For IPv6 support, add IPv6 address structure
-   in the union u. */
-union usa {
-    struct sockaddr sa;
-    struct sockaddr_in sin;
-#if defined(USE_IPV6)
-    struct sockaddr_in6 sin6;
-#endif
-};
-
-/* Describes a string (chunk of memory). */
-struct vec {
-    const char *ptr;
-    size_t len;
-};
-
-struct file {
-    int is_directory;
-    time_t modification_time;
-    int64_t size;
-    FILE *fp;
-    const char *membuf;   /* Non-NULL if file data is in memory */
-    /* set to 1 if the content is gzipped
-       in which case we need a content-encoding: gzip header */
-    int gzipped;
-};
-#define STRUCT_FILE_INITIALIZER {0, 0, 0, NULL, NULL, 0}
-
-/* Describes listening socket, or socket which was accept()-ed by the master
-   thread and queued for future handling by the worker thread. */
-struct socket {
-    SOCKET sock;          /* Listening socket */
-    union usa lsa;        /* Local socket address */
-    union usa rsa;        /* Remote socket address */
-    unsigned is_ssl:1;    /* Is port SSL-ed */
-    unsigned ssl_redir:1; /* Is port supposed to redirect everything to SSL
-                             port */
-};
-
-/* NOTE(lsm): this enum shoulds be in sync with the config_options below. */
-enum {
-    CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
-    PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS, THROTTLE,
-    ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
-    GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
-    EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
-    NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT,
-    DECODE_URL,
-
-#if defined(USE_LUA)
-    LUA_PRELOAD_FILE, LUA_SCRIPT_EXTENSIONS, LUA_SERVER_PAGE_EXTENSIONS,
-#endif
-#if defined(USE_WEBSOCKET)
-    WEBSOCKET_ROOT,
-#endif
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
-    LUA_WEBSOCKET_EXTENSIONS,
-#endif
-    ACCESS_CONTROL_ALLOW_ORIGIN, ERROR_PAGES,
-
-    NUM_OPTIONS
-};
-
-/* Config option name, config types, default value */
-static struct mg_option config_options[] = {
-    {"cgi_pattern",                 CONFIG_TYPE_EXT_PATTERN,   "**.cgi$|**.pl$|**.php$"},
-    {"cgi_environment",             CONFIG_TYPE_STRING,        NULL},
-    {"put_delete_auth_file",        CONFIG_TYPE_FILE,          NULL},
-    {"cgi_interpreter",             CONFIG_TYPE_FILE,          NULL},
-    {"protect_uri",                 CONFIG_TYPE_STRING,        NULL},
-    {"authentication_domain",       CONFIG_TYPE_STRING,        "mydomain.com"},
-    {"ssi_pattern",                 CONFIG_TYPE_EXT_PATTERN,   "**.shtml$|**.shtm$"},
-    {"throttle",                    CONFIG_TYPE_STRING,        NULL},
-    {"access_log_file",             CONFIG_TYPE_FILE,          NULL},
-    {"enable_directory_listing",    CONFIG_TYPE_BOOLEAN,       "yes"},
-    {"error_log_file",              CONFIG_TYPE_FILE,          NULL},
-    {"global_auth_file",            CONFIG_TYPE_FILE,          NULL},
-    {"index_files",                 CONFIG_TYPE_STRING,
-#ifdef USE_LUA
-    "index.xhtml,index.html,index.htm,index.lp,index.lsp,index.lua,index.cgi,index.shtml,index.php"},
-#else
-    "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
-#endif
-    {"enable_keep_alive",           CONFIG_TYPE_BOOLEAN,       "no"},
-    {"access_control_list",         CONFIG_TYPE_STRING,        NULL},
-    {"extra_mime_types",            CONFIG_TYPE_STRING,        NULL},
-    {"listening_ports",             CONFIG_TYPE_STRING,        "8080"},
-    {"document_root",               CONFIG_TYPE_DIRECTORY,     NULL},
-    {"ssl_certificate",             CONFIG_TYPE_FILE,          NULL},
-    {"num_threads",                 CONFIG_TYPE_NUMBER,        "50"},
-    {"run_as_user",                 CONFIG_TYPE_STRING,        NULL},
-    {"url_rewrite_patterns",        CONFIG_TYPE_STRING,        NULL},
-    {"hide_files_patterns",         CONFIG_TYPE_EXT_PATTERN,   NULL},
-    {"request_timeout_ms",          CONFIG_TYPE_NUMBER,        "30000"},
-    {"decode_url",                  CONFIG_TYPE_BOOLEAN,       "yes"},
-
-#if defined(USE_LUA)
-    {"lua_preload_file",            CONFIG_TYPE_FILE,          NULL},
-    {"lua_script_pattern",          CONFIG_TYPE_EXT_PATTERN,   "**.lua$"},
-    {"lua_server_page_pattern",     CONFIG_TYPE_EXT_PATTERN,   "**.lp$|**.lsp$"},
-#endif
-#if defined(USE_WEBSOCKET)
-    {"websocket_root",              CONFIG_TYPE_DIRECTORY,     NULL},
-#endif
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
-    {"lua_websocket_pattern",       CONFIG_TYPE_EXT_PATTERN,   "**.lua$"},
-#endif
-    {"access_control_allow_origin", CONFIG_TYPE_STRING,        "*"},
-    {"error_pages",                 CONFIG_TYPE_DIRECTORY,     NULL},
-
-    {NULL, CONFIG_TYPE_UNKNOWN, NULL}
-};
-
-struct mg_request_handler_info {
-    char *uri;
-    size_t uri_len;
-    mg_request_handler handler;
-
-    void *cbdata;
-    struct mg_request_handler_info *next;
-};
-
-struct mg_context {
-    volatile int stop_flag;         /* Should we stop event loop */
-    SSL_CTX *ssl_ctx;               /* SSL context */
-    char *config[NUM_OPTIONS];      /* Civetweb configuration parameters */
-    struct mg_callbacks callbacks;  /* User-defined callback function */
-    void *user_data;                /* User-defined data */
-    int context_type;               /* 1 = server context, 2 = client context */
-
-    struct socket *listening_sockets;
-    in_port_t *listening_ports;
-    int num_listening_sockets;
-
-    volatile int num_threads;       /* Number of threads */
-    pthread_mutex_t thread_mutex;   /* Protects (max|num)_threads */
-    pthread_cond_t thread_cond;     /* Condvar for tracking workers terminations */
-
-    struct socket queue[MGSQLEN];   /* Accepted sockets */
-    volatile int sq_head;           /* Head of the socket queue */
-    volatile int sq_tail;           /* Tail of the socket queue */
-    pthread_cond_t sq_full;         /* Signaled when socket is produced */
-    pthread_cond_t sq_empty;        /* Signaled when socket is consumed */
-    pthread_t masterthreadid;       /* The master thread ID */
-    int workerthreadcount;          /* The amount of worker threads. */
-    pthread_t *workerthreadids;     /* The worker thread IDs */
-
-    unsigned long start_time;       /* Server start time, used for authentication */
-    pthread_mutex_t nonce_mutex;    /* Protects nonce_count */
-    unsigned long nonce_count;      /* Used nonces, used for authentication */
-
-    char *systemName;               /* What operating system is running */
-
-    /* linked list of uri handlers */
-    struct mg_request_handler_info *request_handlers;
-
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
-    /* linked list of shared lua websockets */
-    struct mg_shared_lua_websocket_list *shared_lua_websockets;
-#endif
-
-#ifdef USE_TIMERS
-    struct ttimers * timers;
-#endif
-};
-
-struct mg_connection {
-    struct mg_request_info request_info;
-    struct mg_context *ctx;
-    SSL *ssl;                       /* SSL descriptor */
-    SSL_CTX *client_ssl_ctx;        /* SSL context for client connections */
-    struct socket client;           /* Connected client */
-    time_t birth_time;              /* Time when request was received */
-    int64_t num_bytes_sent;         /* Total bytes sent to client */
-    int64_t content_len;            /* Content-Length header value */
-    int64_t consumed_content;       /* How many bytes of content have been read */
-    char *buf;                      /* Buffer for received data */
-    char *path_info;                /* PATH_INFO part of the URL */
-    int must_close;                 /* 1 if connection must be closed */
-    int in_error_handler;           /* 1 if in handler for user defined error pages */
-    int buf_size;                   /* Buffer size */
-    int request_len;                /* Size of the request + headers in a buffer */
-    int data_len;                   /* Total size of data in a buffer */
-    int status_code;                /* HTTP reply status code, e.g. 200 */
-    int throttle;                   /* Throttling, bytes/sec. <= 0 means no throttle */
-    time_t last_throttle_time;      /* Last time throttled data was sent */
-    int64_t last_throttle_bytes;    /* Bytes sent this second */
-    pthread_mutex_t mutex;          /* Used by mg_lock_connection/mg_unlock_connection to ensure atomic transmissions for websockets */
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
-    void * lua_websocket_state;     /* Lua_State for a websocket connection */
-#endif
-};
-
-static pthread_key_t sTlsKey;  /* Thread local storage index */
-static int sTlsInit = 0;
-
-struct mg_workerTLS {
-    int is_master;
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
-    HANDLE pthread_cond_helper_mutex;
-#endif
-};
-
-/* Directory entry */
-struct de {
-    struct mg_connection *conn;
-    char *file_name;
-    struct file file;
-};
-
-#if defined(USE_WEBSOCKET)
-static int is_websocket_protocol(const struct mg_connection *conn);
-#else
-#define is_websocket_protocol(conn) (0)
-#endif
-
-int mg_atomic_inc(volatile int * addr)
-{
-    int ret;
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
-    ret = InterlockedIncrement((volatile unsigned int *) addr);
-#elif defined(__GNUC__)
-    ret = __sync_add_and_fetch(addr, 1);
-#else
-    ret = (++(*addr));
-#endif
-    return ret;
-}
-
-int mg_atomic_dec(volatile int * addr)
-{
-    int ret;
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
-    ret = InterlockedDecrement((volatile unsigned int *) addr);
-#elif defined(__GNUC__)
-    ret = __sync_sub_and_fetch(addr, 1);
-#else
-    ret = (--(*addr));
-#endif
-    return ret;
-}
-
-#if !defined(NO_THREAD_NAME)
-#if defined(_WIN32) && defined(_MSC_VER)
-/* Set the thread name for debugging purposes in Visual Studio
-   http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
-*/
-#pragma pack(push,8)
-typedef struct tagTHREADNAME_INFO
-{
-   DWORD dwType;     /* Must be 0x1000. */
-   LPCSTR szName;    /* Pointer to name (in user addr space). */
-   DWORD dwThreadID; /* Thread ID (-1=caller thread). */
-   DWORD dwFlags;    /* Reserved for future use, must be zero. */
-} THREADNAME_INFO;
-#pragma pack(pop)
-#elif defined(__linux__)
-#include <sys/prctl.h>
-#endif
-
-void mg_set_thread_name(const char* name)
-{
-    char threadName[16]; /* Max. thread length in Linux/OSX/.. */
-
-    if (snprintf(threadName, sizeof(threadName), "civetweb-%s", name)<0) return;
-    threadName[sizeof(threadName)-1] = 0;
-
-#if defined(_WIN32)
-#if defined(_MSC_VER)
-    /* Windows and Visual Studio Compiler */
-    __try
-    {
-        THREADNAME_INFO info;
-        info.dwType     = 0x1000;
-        info.szName     = threadName;
-        info.dwThreadID = -1;
-        info.dwFlags    = 0;
-
-        RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
-    }
-    __except(EXCEPTION_EXECUTE_HANDLER)
-    {
-    }
-#elif defined(__MINGW32__)
-   /* No option known to set thread name for MinGW */
-#endif
-#elif defined(__linux__)
-   /* Linux */
-   (void)prctl(PR_SET_NAME,threadName,0,0,0);
-#elif defined(__APPLE__) || defined(__MACH__)
-   /* OS X (TODO: test) */
-   (void)pthread_setname_np(threadName);
-#elif defined(BSD) || defined(__FreeBSD__) || defined(__OpenBSD__)
-   /* BSD (TODO: test) */
-   pthread_set_name_np(pthread_self(), threadName);
-#else
-   /* POSIX */
-   (void)pthread_setname_np(pthread_self(), threadName);
-#endif
-}
-#else /* !defined(NO_THREAD_NAME) */
-void mg_set_thread_name(const char* threadName) {}
-#endif
-
-#if defined(MG_LEGACY_INTERFACE)
-const char **mg_get_valid_option_names(void)
-{
-    static const char * data[2 * sizeof(config_options) / sizeof(config_options[0])] = {0};
-    int i;
-
-    for (i=0; config_options[i].name != NULL; i++) {
-        data[i * 2] = config_options[i].name;
-        data[i * 2 + 1] = config_options[i].default_value;
-    }
-
-    return data;
-}
-#endif
-
-const struct mg_option *mg_get_valid_options(void)
-{
-    return config_options;
-}
-
-
-static int is_file_in_memory(struct mg_connection *conn, const char *path,
-                             struct file *filep)
-{
-    size_t size = 0;
-    if ((filep->membuf = conn->ctx->callbacks.open_file == NULL ? NULL :
-                         conn->ctx->callbacks.open_file(conn, path, &size)) != NULL) {
-        /* NOTE: override filep->size only on success. Otherwise, it might
-           break constructs like if (!mg_stat() || !mg_fopen()) ... */
-        filep->size = size;
-    }
-    return filep->membuf != NULL;
-}
-
-static int is_file_opened(const struct file *filep)
-{
-    return filep->membuf != NULL || filep->fp != NULL;
-}
-
-static int mg_fopen(struct mg_connection *conn, const char *path,
-                    const char *mode, struct file *filep)
-{
-    if (!is_file_in_memory(conn, path, filep)) {
-#ifdef _WIN32
-        wchar_t wbuf[PATH_MAX], wmode[20];
-        to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
-        MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, ARRAY_SIZE(wmode));
-        filep->fp = _wfopen(wbuf, wmode);
-#else
-        filep->fp = fopen(path, mode);
-#endif
-    }
-
-    return is_file_opened(filep);
-}
-
-static void mg_fclose(struct file *filep)
-{
-    if (filep != NULL && filep->fp != NULL) {
-        fclose(filep->fp);
-    }
-}
-
-static void mg_strlcpy(register char *dst, register const char *src, size_t n)
-{
-    for (; *src != '\0' && n > 1; n--) {
-        *dst++ = *src++;
-    }
-    *dst = '\0';
-}
-
-static int lowercase(const char *s)
-{
-    return tolower(* (const unsigned char *) s);
-}
-
-int mg_strncasecmp(const char *s1, const char *s2, size_t len)
-{
-    int diff = 0;
-
-    if (len > 0)
-        do {
-            diff = lowercase(s1++) - lowercase(s2++);
-        } while (diff == 0 && s1[-1] != '\0' && --len > 0);
-
-    return diff;
-}
-
-static int mg_strcasecmp(const char *s1, const char *s2)
-{
-    int diff;
-
-    do {
-        diff = lowercase(s1++) - lowercase(s2++);
-    } while (diff == 0 && s1[-1] != '\0');
-
-    return diff;
-}
-
-static char * mg_strndup(const char *ptr, size_t len)
-{
-    char *p;
-
-    if ((p = (char *) mg_malloc(len + 1)) != NULL) {
-        mg_strlcpy(p, ptr, len + 1);
-    }
-
-    return p;
-}
-
-static char * mg_strdup(const char *str)
-{
-    return mg_strndup(str, strlen(str));
-}
-
-static const char *mg_strcasestr(const char *big_str, const char *small_str)
-{
-    int i, big_len = (int)strlen(big_str), small_len = (int)strlen(small_str);
-
-    for (i = 0; i <= big_len - small_len; i++) {
-        if (mg_strncasecmp(big_str + i, small_str, small_len) == 0) {
-            return big_str + i;
-        }
-    }
-
-    return NULL;
-}
-
-/* Like snprintf(), but never returns negative value, or a value
-   that is larger than a supplied buffer.
-   Thanks to Adam Zeldis to pointing snprintf()-caused vulnerability
-   in his audit report. */
-static int mg_vsnprintf(struct mg_connection *conn, char *buf, size_t buflen,
-                        const char *fmt, va_list ap)
-{
-    int n;
-
-    if (buflen == 0)
-        return 0;
-
-    n = vsnprintf(buf, buflen, fmt, ap);
-
-    if (n < 0) {
-        mg_cry(conn, "vsnprintf error");
-        n = 0;
-    } else if (n >= (int) buflen) {
-        mg_cry(conn, "truncating vsnprintf buffer: [%.*s]",
-               n > 200 ? 200 : n, buf);
-        n = (int) buflen - 1;
-    }
-    buf[n] = '\0';
-
-    return n;
-}
-
-static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
-                       PRINTF_FORMAT_STRING(const char *fmt), ...)
-PRINTF_ARGS(4, 5);
-
-static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
-                       const char *fmt, ...)
-{
-    va_list ap;
-    int n;
-
-    va_start(ap, fmt);
-    n = mg_vsnprintf(conn, buf, buflen, fmt, ap);
-    va_end(ap);
-
-    return n;
-}
-
-static int get_option_index(const char *name)
-{
-    int i;
-
-    for (i = 0; config_options[i].name != NULL; i++) {
-        if (strcmp(config_options[i].name, name) == 0) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-const char *mg_get_option(const struct mg_context *ctx, const char *name)
-{
-    int i;
-    if ((i = get_option_index(name)) == -1) {
-        return NULL;
-    } else if (ctx->config[i] == NULL) {
-        return "";
-    } else {
-        return ctx->config[i];
-    }
-}
-
-struct mg_context *mg_get_context(struct mg_connection * conn)
-{
-    return (conn == NULL) ? (struct mg_context *)NULL : (conn->ctx);
-}
-
-void *mg_get_user_data(struct mg_context *ctx)
-{
-    return (ctx == NULL) ? NULL : ctx->user_data;
-}
-
-size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl)
-{
-    size_t i;
-    for (i = 0; i < size && i < (size_t)ctx->num_listening_sockets; i++)
-    {
-        ssl[i] = ctx->listening_sockets[i].is_ssl;
-        ports[i] = ctx->listening_ports[i];
-    }
-    return i;
-}
-
-static void sockaddr_to_string(char *buf, size_t len,
-                               const union usa *usa)
-{
-    buf[0] = '\0';
-#if defined(USE_IPV6)
-    inet_ntop(usa->sa.sa_family, usa->sa.sa_family == AF_INET ?
-              (void *) &usa->sin.sin_addr :
-              (void *) &usa->sin6.sin6_addr, buf, len);
-#elif defined(_WIN32)
-    /* Only Windows Vista (and newer) have inet_ntop() */
-    mg_strlcpy(buf, inet_ntoa(usa->sin.sin_addr), len);
-#else
-    inet_ntop(usa->sa.sa_family, (void *) &usa->sin.sin_addr, buf, len);
-#endif
-}
-
-/* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be included in all responses other than 100, 101, 5xx. */
-static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
-{
-    struct tm *tm;
-
-    tm = gmtime(t);
-    if (tm != NULL) {
-        strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
-    } else {
-        mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
-        buf[buf_len - 1] = '\0';
-    }
-}
-
-/* Print error message to the opened error log stream. */
-void mg_cry(struct mg_connection *conn, const char *fmt, ...)
-{
-    char buf[MG_BUF_LEN], src_addr[IP_ADDR_STR_LEN];
-    va_list ap;
-    FILE *fp;
-    time_t timestamp;
-
-    va_start(ap, fmt);
-    IGNORE_UNUSED_RESULT(vsnprintf(buf, sizeof(buf), fmt, ap));
-    va_end(ap);
-
-    /* Do not lock when getting the callback value, here and below.
-       I suppose this is fine, since function cannot disappear in the
-       same way string option can. */
-    if (conn->ctx->callbacks.log_message == NULL ||
-        conn->ctx->callbacks.log_message(conn, buf) == 0) {
-        fp = conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL :
-             fopen(conn->ctx->config[ERROR_LOG_FILE], "a+");
-
-        if (fp != NULL) {
-            flockfile(fp);
-            timestamp = time(NULL);
-
-            sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
-            fprintf(fp, "[%010lu] [error] [client %s] ", (unsigned long) timestamp,
-                    src_addr);
-
-            if (conn->request_info.request_method != NULL) {
-                fprintf(fp, "%s %s: ", conn->request_info.request_method,
-                        conn->request_info.uri);
-            }
-
-            fprintf(fp, "%s", buf);
-            fputc('\n', fp);
-            funlockfile(fp);
-            fclose(fp);
-        }
-    }
-}
-
-/* Return fake connection structure. Used for logging, if connection
-   is not applicable at the moment of logging. */
-static struct mg_connection *fc(struct mg_context *ctx)
-{
-    static struct mg_connection fake_connection;
-    fake_connection.ctx = ctx;
-    return &fake_connection;
-}
-
-const char *mg_version(void)
-{
-    return CIVETWEB_VERSION;
-}
-
-struct mg_request_info *mg_get_request_info(struct mg_connection *conn)
-{
-    return &conn->request_info;
-}
-
-/* Skip the characters until one of the delimiters characters found.
-   0-terminate resulting word. Skip the delimiter and following whitespaces.
-   Advance pointer to buffer to the next word. Return found 0-terminated word.
-   Delimiters can be quoted with quotechar. */
-static char *skip_quoted(char **buf, const char *delimiters,
-                         const char *whitespace, char quotechar)
-{
-    char *p, *begin_word, *end_word, *end_whitespace;
-
-    begin_word = *buf;
-    end_word = begin_word + strcspn(begin_word, delimiters);
-
-    /* Check for quotechar */
-    if (end_word > begin_word) {
-        p = end_word - 1;
-        while (*p == quotechar) {
-            /* TODO (bel): it seems this code is never reached, so quotechar is actually
-               not needed - check if this code may be droped */
-
-            /* If there is anything beyond end_word, copy it */
-            if (*end_word == '\0') {
-                *p = '\0';
-                break;
-            } else {
-                size_t end_off = strcspn(end_word + 1, delimiters);
-                memmove (p, end_word, end_off + 1);
-                p += end_off; /* p must correspond to end_word - 1 */
-                end_word += end_off + 1;
-            }
-        }
-        for (p++; p < end_word; p++) {
-            *p = '\0';
-        }
-    }
-
-    if (*end_word == '\0') {
-        *buf = end_word;
-    } else {
-        end_whitespace = end_word + 1 + strspn(end_word + 1, whitespace);
-
-        for (p = end_word; p < end_whitespace; p++) {
-            *p = '\0';
-        }
-
-        *buf = end_whitespace;
-    }
-
-    return begin_word;
-}
-
-/* Simplified version of skip_quoted without quote char
-   and whitespace == delimiters */
-static char *skip(char **buf, const char *delimiters)
-{
-    return skip_quoted(buf, delimiters, delimiters, 0);
-}
-
-
-/* Return HTTP header value, or NULL if not found. */
-static const char *get_header(const struct mg_request_info *ri,
-                              const char *name)
-{
-    int i;
-
-    for (i = 0; i < ri->num_headers; i++)
-        if (!mg_strcasecmp(name, ri->http_headers[i].name))
-            return ri->http_headers[i].value;
-
-    return NULL;
-}
-
-const char *mg_get_header(const struct mg_connection *conn, const char *name)
-{
-    return get_header(&conn->request_info, name);
-}
-
-/* A helper function for traversing a comma separated list of values.
-   It returns a list pointer shifted to the next value, or NULL if the end
-   of the list found.
-   Value is stored in val vector. If value has form "x=y", then eq_val
-   vector is initialized to point to the "y" part, and val vector length
-   is adjusted to point only to "x". */
-static const char *next_option(const char *list, struct vec *val,
-                               struct vec *eq_val)
-{
-    if (list == NULL || *list == '\0') {
-        /* End of the list */
-        list = NULL;
-    } else {
-        val->ptr = list;
-        if ((list = strchr(val->ptr, ',')) != NULL) {
-            /* Comma found. Store length and shift the list ptr */
-            val->len = list - val->ptr;
-            list++;
-        } else {
-            /* This value is the last one */
-            list = val->ptr + strlen(val->ptr);
-            val->len = list - val->ptr;
-        }
-
-        if (eq_val != NULL) {
-            /* Value has form "x=y", adjust pointers and lengths
-               so that val points to "x", and eq_val points to "y". */
-            eq_val->len = 0;
-            eq_val->ptr = (const char *) memchr(val->ptr, '=', val->len);
-            if (eq_val->ptr != NULL) {
-                eq_val->ptr++;  /* Skip over '=' character */
-                eq_val->len = val->ptr + val->len - eq_val->ptr;
-                val->len = (eq_val->ptr - val->ptr) - 1;
-            }
-        }
-    }
-
-    return list;
-}
-
-/* Perform case-insensitive match of string against pattern */
-static int match_prefix(const char *pattern, int pattern_len, const char *str)
-{
-    const char *or_str;
-    int i, j, len, res;
-
-    if ((or_str = (const char *) memchr(pattern, '|', pattern_len)) != NULL) {
-        res = match_prefix(pattern, (int)(or_str - pattern), str);
-        return res > 0 ? res :
-               match_prefix(or_str + 1, (int)((pattern + pattern_len) - (or_str + 1)), str);
-    }
-
-    i = j = 0;
-    for (; i < pattern_len; i++, j++) {
-        if (pattern[i] == '?' && str[j] != '\0') {
-            continue;
-        } else if (pattern[i] == '$') {
-            return str[j] == '\0' ? j : -1;
-        } else if (pattern[i] == '*') {
-            i++;
-            if (pattern[i] == '*') {
-                i++;
-                len = (int) strlen(str + j);
-            } else {
-                len = (int) strcspn(str + j, "/");
-            }
-            if (i == pattern_len) {
-                return j + len;
-            }
-            do {
-                res = match_prefix(pattern + i, pattern_len - i, str + j + len);
-            } while (res == -1 && len-- > 0);
-            return res == -1 ? -1 : j + res + len;
-        } else if (lowercase(&pattern[i]) != lowercase(&str[j])) {
-            return -1;
-        }
-    }
-    return j;
-}
-
-/* HTTP 1.1 assumes keep alive if "Connection:" header is not set
-   This function must tolerate situations when connection info is not
-   set up, for example if request parsing failed. */
-static int should_keep_alive(const struct mg_connection *conn)
-{
-    const char *http_version = conn->request_info.http_version;
-    const char *header = mg_get_header(conn, "Connection");
-    if (conn->must_close ||
-        conn->status_code == 401 ||
-        mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 ||
-        (header != NULL && mg_strcasecmp(header, "keep-alive") != 0) ||
-        (header == NULL && http_version && 0!=strcmp(http_version, "1.1"))) {
-        return 0;
-    }
-    return 1;
-}
-
-static int should_decode_url(const struct mg_connection *conn)
-{
-    return (mg_strcasecmp(conn->ctx->config[DECODE_URL], "yes") == 0);
-}
-
-static const char *suggest_connection_header(const struct mg_connection *conn)
-{
-    return should_keep_alive(conn) ? "keep-alive" : "close";
-}
-
-static void handle_file_based_request(struct mg_connection *conn, const char *path, struct file *filep);
-static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep);
-
-static const char *mg_get_response_code_text(int response_code, struct mg_connection *conn)
-{
-    switch (response_code)
-    {
-    /* RFC2616 Section 10.1 - Informational 1xx */
-    case 100: return "Continue"; /* RFC2616 Section 10.1.1 */
-    case 101: return "Switching Protocols"; /* RFC2616 Section 10.1.2 */
-    case 102: return "Processing"; /* RFC2518 Section 10.1 */
-
-    /* RFC2616 Section 10.2 - Successful 2xx */
-    case 200: return "OK"; /* RFC2616 Section 10.2.1 */
-    case 201: return "Created"; /* RFC2616 Section 10.2.2 */
-    case 202: return "Accepted"; /* RFC2616 Section 10.2.3 */
-    case 203: return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */
-    case 204: return "No Content"; /* RFC2616 Section 10.2.5 */
-    case 205: return "Reset Content"; /* RFC2616 Section 10.2.6 */
-    case 206: return "Partial Content"; /* RFC2616 Section 10.2.7 */
-    case 207: return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1 */
-
-    /* RFC2616 Section 10.3 - Redirection 3xx */
-    case 300: return "Multiple Choices"; /* RFC2616 Section 10.3.1 */
-    case 301: return "Moved Permanently"; /* RFC2616 Section 10.3.2 */
-    case 302: return "Found"; /* RFC2616 Section 10.3.3 */
-    case 303: return "See Other"; /* RFC2616 Section 10.3.4 */
-    case 304: return "Not Modified"; /* RFC2616 Section 10.3.5 */
-    case 305: return "Use Proxy"; /* RFC2616 Section 10.3.6 */
-    case 307: return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */
-
-    /* RFC2616 Section 10.4 - Client Error 4xx */
-    case 400: return "Bad Request"; /* RFC2616 Section 10.4.1 */
-    case 401: return "Unauthorized"; /* RFC2616 Section 10.4.2 */
-    case 402: return "Payment Required"; /* RFC2616 Section 10.4.3 */
-    case 403: return "Forbidden"; /* RFC2616 Section 10.4.4 */
-    case 404: return "Not Found"; /* RFC2616 Section 10.4.5 */
-    case 405: return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */
-    case 406: return "Not Acceptable"; /* RFC2616 Section 10.4.7 */
-    case 407: return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */
-    case 408: return "Request Time-out"; /* RFC2616 Section 10.4.9 */
-    case 409: return "Conflict"; /* RFC2616 Section 10.4.10 */
-    case 410: return "Gone"; /* RFC2616 Section 10.4.11 */
-    case 411: return "Length Required"; /* RFC2616 Section 10.4.12 */
-    case 412: return "Precondition Failed"; /* RFC2616 Section 10.4.13 */
-    case 413: return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */
-    case 414: return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */
-    case 415: return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */
-    case 416: return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17 */
-    case 417: return "Expectation Failed"; /* RFC2616 Section 10.4.18 */
-    case 422: return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918 Section 11.2 */
-    case 423: return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */
-    case 424: return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918 Section 11.4 */
-    case 428: return "Precondition Required"; /* RFC 6585, Section 3 */
-    case 429: return "Too Many Requests"; /* RFC 6585, Section 4 */
-    case 431: return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */
-
-    /* RFC2616 Section 10.5 - Server Error 5xx */
-    case 500: return "Internal Server Error"; /* RFC2616 Section 10.5.1 */
-    case 501: return "Not Implemented"; /* RFC2616 Section 10.5.2 */
-    case 502: return "Bad Gateway"; /* RFC2616 Section 10.5.3 */
-    case 503: return "Service Unavailable"; /* RFC2616 Section 10.5.4 */
-    case 504: return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */
-    case 505: return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */
-    case 507: return "Insufficient Storage"; /* RFC2518 Section 10.6, , RFC4918 Section 11.5 */
-    case 511: return "Network Authentication Required"; /* RFC 6585, Section 6 */
-
-    /* Other RFCs */
-    case 426: return "Upgrade Required"; /* RFC 2817 */
-
-    /* Return codes from non normative RFCs: */
-    /* Informative and experimental RFCs, "de facto" standards due to common use, ... */
-    case 208: return "Already Reported"; /* RFC5842 Section 7.1 */
-    case 226: return "IM used"; /* RFC3229 Section 10.4.1 */
-    case 308: return "Permanent Redirect"; /* RFC7238 Section 3 */
-    case 418: return "I am a teapot"; /* RFC2324 Section 2.3.2 */
-    case 419: return "Authentication Timeout"; /* common use */
-    case 451: return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05, Section 3 */
-    case 506: return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */
-    case 508: return "Loop Detected"; /* RFC5842 Section 7.1 */
-    case 510: return "Not Extended"; /* RFC 2774, Section 7 */
-
-    default:
-        /* This error code is unknown. This should not happen. */
-        if (conn) {
-            mg_cry(conn, "Unknown HTTP response code: %u", response_code);
-        }
-
-        /* Return at least a category according to RFC 2616 Section 10. */
-        if (response_code>=100 && response_code<200) {
-            /* Unknown informational status code */
-            return "Information";
-        }
-        if (response_code>=200 && response_code<300) {
-            /* Unknown success code */
-            return "Success";
-        }
-        if (response_code>=300 && response_code<400) {
-            /* Unknown redirection code */
-            return "Redirection";
-        }
-        if (response_code>=400 && response_code<500) {
-            /* Unknown request error code */
-            return "Client Error";
-        }
-        if (response_code>=500 && response_code<600) {
-            /* Unknown server error code */
-            return "Server Error";
-        }
-
-        /* Response code not even within reasonable range */
-        return "";
-    }
-}
-
-
-static void send_http_error(struct mg_connection *, int, const char *,
-                            PRINTF_FORMAT_STRING(const char *fmt), ...)
-PRINTF_ARGS(4, 5);
-
-
-static void send_http_error(struct mg_connection *conn, int status,
-                            const char *reason, const char *fmt, ...)
-{
-    char buf[MG_BUF_LEN];
-    va_list ap;
-    int len = 0, i, page_handler_found, scope;
-    char date[64];
-    time_t curtime = time(NULL);
-    const char *error_handler = NULL;
-    struct file error_page_file = STRUCT_FILE_INITIALIZER;
-    const char *error_page_file_ext, *tstr;
-
-    if (!reason) {
-        reason = mg_get_response_code_text(status, conn);
-    }
-
-    conn->status_code = status;
-    if (conn->in_error_handler ||
-        conn->ctx->callbacks.http_error == NULL ||
-        conn->ctx->callbacks.http_error(conn, status)) {
-
-        if (!conn->in_error_handler) {
-            /* Send user defined error pages, if defined */
-            error_handler = conn->ctx->config[ERROR_PAGES];
-            error_page_file_ext = conn->ctx->config[INDEX_FILES];
-            page_handler_found = 0;
-            if (error_handler != NULL) {
-                for (scope=1; (scope<=3) && !page_handler_found; scope++) {
-                    switch (scope) {
-                    case 1:
-                        len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%03u.", error_handler, status);
-                        break;
-                    case 2:
-                        len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%01uxx.", error_handler, status/100);
-                        break;
-                    default:
-                        len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror.", error_handler);
-                        break;
-                    }
-                    tstr = strchr(error_page_file_ext, '.');
-                    while (tstr) {
-                        for (i=1; i<32 && tstr[i]!=0 && tstr[i]!=','; i++) buf[len+i-1]=tstr[i];
-                        buf[len+i-1]=0;
-                        if (mg_stat(conn, buf, &error_page_file)) {
-                            page_handler_found = 1;
-                            break;
-                        }
-                        tstr = strchr(tstr+i, '.');
-                    }
-                }
-            }
-
-            if (page_handler_found) {
-                conn->in_error_handler = 1;
-                handle_file_based_request(conn, buf, &error_page_file);
-                conn->in_error_handler = 0;
-                return;
-            }
-        }
-
-        buf[0] = '\0';
-        gmt_time_string(date, sizeof(date), &curtime);
-
-        /* Errors 1xx, 204 and 304 MUST NOT send a body */
-        if (status > 199 && status != 204 && status != 304) {
-            len = mg_snprintf(conn, buf, sizeof(buf)-1, "Error %d: %s", status, reason);
-            buf[len] = '\n';
-            len++;
-            buf[len] = 0;
-
-            va_start(ap, fmt);
-            len += mg_vsnprintf(conn, buf + len, sizeof(buf) - len, fmt, ap);
-            va_end(ap);
-        }
-        DEBUG_TRACE("[%s]", buf);
-
-        mg_printf(conn, "HTTP/1.1 %d %s\r\n"
-                        "Content-Length: %d\r\n"
-                        "Date: %s\r\n"
-                        "Connection: %s\r\n\r\n",
-                        status, reason, len, date,
-                        suggest_connection_header(conn));
-        conn->num_bytes_sent += mg_printf(conn, "%s", buf);
-    }
-}
-
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
-static int pthread_mutex_init(pthread_mutex_t *mutex, void *unused)
-{
-    (void) unused;
-    *mutex = CreateMutex(NULL, FALSE, NULL);
-    return *mutex == NULL ? -1 : 0;
-}
-
-static int pthread_mutex_destroy(pthread_mutex_t *mutex)
-{
-    return CloseHandle(*mutex) == 0 ? -1 : 0;
-}
-
-static int pthread_mutex_lock(pthread_mutex_t *mutex)
-{
-    return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
-}
-
-static int pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
-    switch (WaitForSingleObject(*mutex, 0)) {
-        case WAIT_OBJECT_0:
-            return 0;
-        case WAIT_TIMEOUT:
-            return -2; /* EBUSY */
-    }
-    return -1;
-}
-
-static int pthread_mutex_unlock(pthread_mutex_t *mutex)
-{
-    return ReleaseMutex(*mutex) == 0 ? -1 : 0;
-}
-
-#ifndef WIN_PTHREADS_TIME_H
-static int clock_gettime(clockid_t clk_id, struct timespec *tp)
-{
-    FILETIME ft;
-    ULARGE_INTEGER li;
-    BOOL ok = FALSE;
-    double d;
-    static double perfcnt_per_sec = 0.0;
-
-    if (tp) {
-        if (clk_id == CLOCK_REALTIME) {
-            GetSystemTimeAsFileTime(&ft);
-            li.LowPart = ft.dwLowDateTime;
-            li.HighPart = ft.dwHighDateTime;
-            li.QuadPart -= 116444736000000000; /* 1.1.1970 in filedate */
-            tp->tv_sec = (time_t)(li.QuadPart / 10000000);
-            tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
-            ok = TRUE;
-        } else if (clk_id == CLOCK_MONOTONIC) {
-            if (perfcnt_per_sec == 0.0) {
-                QueryPerformanceFrequency((LARGE_INTEGER *) &li);
-                perfcnt_per_sec = 1.0 / li.QuadPart;
-            }
-            if (perfcnt_per_sec != 0.0) {
-                QueryPerformanceCounter((LARGE_INTEGER *) &li);
-                d = li.QuadPart * perfcnt_per_sec;
-                tp->tv_sec = (time_t)d;
-                d -= tp->tv_sec;
-                tp->tv_nsec = (long)(d*1.0E9);
-                ok = TRUE;
-            }
-        }
-    }
-
-    return ok ? 0 : -1;
-}
-#endif
-
-static int pthread_cond_init(pthread_cond_t *cv, const void *unused)
-{
-    (void) unused;
-    InitializeCriticalSection(&cv->threadIdSec);
-    cv->waitingthreadcount = 0;
-    cv->waitingthreadhdls = (pthread_t *) mg_calloc(MAX_WORKER_THREADS, sizeof(pthread_t));
-    return (cv->waitingthreadhdls!=NULL) ? 0 : -1;
-}
-
-static int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec * abstime)
-{
-    struct mg_workerTLS * tls = (struct mg_workerTLS *)TlsGetValue(sTlsKey);
-    int ok;
-    struct timespec tsnow;
-    int64_t nsnow, nswaitabs, nswaitrel;
-    DWORD mswaitrel;
-
-    EnterCriticalSection(&cv->threadIdSec);
-    assert(cv->waitingthreadcount < MAX_WORKER_THREADS);
-    cv->waitingthreadhdls[cv->waitingthreadcount] = tls->pthread_cond_helper_mutex;
-    cv->waitingthreadcount++;
-    LeaveCriticalSection(&cv->threadIdSec);
-
-    if (abstime) {
-        clock_gettime(CLOCK_REALTIME, &tsnow);
-        nsnow = (((uint64_t)tsnow.tv_sec)*1000000000) + tsnow.tv_nsec;
-        nswaitabs = (((uint64_t)abstime->tv_sec)*1000000000) + abstime->tv_nsec;
-        nswaitrel = nswaitabs - nsnow;
-        if (nswaitrel<0) nswaitrel=0;
-        mswaitrel = (DWORD)(nswaitrel / 1000000);
-    } else {
-        mswaitrel = INFINITE;
-    }
-
-    pthread_mutex_unlock(mutex);
-    ok = (WAIT_OBJECT_0 == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel));
-    pthread_mutex_lock(mutex);
-
-    return ok ? 0 : -1;
-}
-
-static int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex)
-{
-    return pthread_cond_timedwait(cv, mutex, NULL);
-}
-
-static int pthread_cond_signal(pthread_cond_t *cv)
-{
-    int i;
-    HANDLE wkup = NULL;
-    BOOL ok = FALSE;
-
-    EnterCriticalSection(&cv->threadIdSec);
-    if (cv->waitingthreadcount) {
-        wkup = cv->waitingthreadhdls[0];
-        ok = SetEvent(wkup);
-
-        for (i=1; i<cv->waitingthreadcount; i++) {
-            cv->waitingthreadhdls[i-1] = cv->waitingthreadhdls[i];
-        }
-        cv->waitingthreadcount--;
-
-        assert(ok);
-    }
-    LeaveCriticalSection(&cv->threadIdSec);
-
-    return ok ? 0 : 1;
-}
-
-static int pthread_cond_broadcast(pthread_cond_t *cv)
-{
-    EnterCriticalSection(&cv->threadIdSec);
-    while (cv->waitingthreadcount) {
-        pthread_cond_signal(cv);
-    }
-    LeaveCriticalSection(&cv->threadIdSec);
-
-    return 0;
-}
-
-static int pthread_cond_destroy(pthread_cond_t *cv)
-{
-    EnterCriticalSection(&cv->threadIdSec);
-    assert(cv->waitingthreadcount==0);
-    mg_free(cv->waitingthreadhdls);
-    cv->waitingthreadhdls = 0;
-    LeaveCriticalSection(&cv->threadIdSec);
-    DeleteCriticalSection(&cv->threadIdSec);
-
-    return 0;
-}
-
-/* For Windows, change all slashes to backslashes in path names. */
-static void change_slashes_to_backslashes(char *path)
-{
-    int i;
-
-    for (i = 0; path[i] != '\0'; i++) {
-        if (path[i] == '/')
-            path[i] = '\\';
-        /* i > 0 check is to preserve UNC paths, like \\server\file.txt */
-        if (path[i] == '\\' && i > 0)
-            while (path[i + 1] == '\\' || path[i + 1] == '/')
-                (void) memmove(path + i + 1,
-                               path + i + 2, strlen(path + i + 1));
-    }
-}
-
-/* Encode 'path' which is assumed UTF-8 string, into UNICODE string.
-   wbuf and wbuf_len is a target buffer and its length. */
-static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len)
-{
-    char buf[PATH_MAX], buf2[PATH_MAX];
-
-    mg_strlcpy(buf, path, sizeof(buf));
-    change_slashes_to_backslashes(buf);
-
-    /* Convert to Unicode and back. If doubly-converted string does not
-       match the original, something is fishy, reject. */
-    memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
-    MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
-    WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
-                        NULL, NULL);
-    if (strcmp(buf, buf2) != 0) {
-        wbuf[0] = L'\0';
-    }
-}
-
-#if defined(_WIN32_WCE)
-static time_t time(time_t *ptime)
-{
-    time_t t;
-    SYSTEMTIME st;
-    FILETIME ft;
-
-    GetSystemTime(&st);
-    SystemTimeToFileTime(&st, &ft);
-    t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime);
-
-    if (ptime != NULL) {
-        *ptime = t;
-    }
-
-    return t;
-}
-
-static struct tm *localtime(const time_t *ptime, struct tm *ptm)
-{
-    int64_t t = ((int64_t) *ptime) * RATE_DIFF + EPOCH_DIFF;
-    FILETIME ft, lft;
-    SYSTEMTIME st;
-    TIME_ZONE_INFORMATION tzinfo;
-
-    if (ptm == NULL) {
-        return NULL;
-    }
-
-    * (int64_t *) &ft = t;
-    FileTimeToLocalFileTime(&ft, &lft);
-    FileTimeToSystemTime(&lft, &st);
-    ptm->tm_year = st.wYear - 1900;
-    ptm->tm_mon = st.wMonth - 1;
-    ptm->tm_wday = st.wDayOfWeek;
-    ptm->tm_mday = st.wDay;
-    ptm->tm_hour = st.wHour;
-    ptm->tm_min = st.wMinute;
-    ptm->tm_sec = st.wSecond;
-    ptm->tm_yday = 0; /* hope nobody uses this */
-    ptm->tm_isdst =
-        GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT ? 1 : 0;
-
-    return ptm;
-}
-
-static struct tm *gmtime(const time_t *ptime, struct tm *ptm)
-{
-    /* FIXME(lsm): fix this. */
-    return localtime(ptime, ptm);
-}
-
-static size_t strftime(char *dst, size_t dst_size, const char *fmt,
-                       const struct tm *tm)
-{
-    (void) snprintf(dst, dst_size, "implement strftime() for WinCE");
-    return 0;
-}
-#endif
-
-/* Windows happily opens files with some garbage at the end of file name.
-   For example, fopen("a.cgi    ", "r") on Windows successfully opens
-   "a.cgi", despite one would expect an error back.
-   This function returns non-0 if path ends with some garbage. */
-static int path_cannot_disclose_cgi(const char *path)
-{
-    static const char *allowed_last_characters = "_-";
-    int last = path[strlen(path) - 1];
-    return isalnum(last) || strchr(allowed_last_characters, last) != NULL;
-}
-
-static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
-{
-    wchar_t wbuf[PATH_MAX];
-    WIN32_FILE_ATTRIBUTE_DATA info;
-
-    if (!is_file_in_memory(conn, path, filep)) {
-        to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
-        if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
-            filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
-            filep->modification_time = SYS2UNIX_TIME(
-                                           info.ftLastWriteTime.dwLowDateTime,
-                                           info.ftLastWriteTime.dwHighDateTime);
-            filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
-            /* If file name is fishy, reset the file structure and return
-               error.
-               Note it is important to reset, not just return the error, cause
-               functions like is_file_opened() check the struct. */
-            if (!filep->is_directory && !path_cannot_disclose_cgi(path)) {
-                memset(filep, 0, sizeof(*filep));
-            }
-        }
-    }
-
-    return filep->membuf != NULL || filep->modification_time != 0;
-}
-
-static int mg_remove(const char *path)
-{
-    wchar_t wbuf[PATH_MAX];
-    to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
-    return DeleteFileW(wbuf) ? 0 : -1;
-}
-
-static int mg_mkdir(const char *path, int mode)
-{
-    char buf[PATH_MAX];
-    wchar_t wbuf[PATH_MAX];
-
-    (void) mode;
-    mg_strlcpy(buf, path, sizeof(buf));
-    change_slashes_to_backslashes(buf);
-
-    (void) MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, ARRAY_SIZE(wbuf));
-
-    return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
-}
-
-/* Implementation of POSIX opendir/closedir/readdir for Windows. */
-static DIR * opendir(const char *name)
-{
-    DIR *dir = NULL;
-    wchar_t wpath[PATH_MAX];
-    DWORD attrs;
-
-    if (name == NULL) {
-        SetLastError(ERROR_BAD_ARGUMENTS);
-    } else if ((dir = (DIR *) mg_malloc(sizeof(*dir))) == NULL) {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-    } else {
-        to_unicode(name, wpath, ARRAY_SIZE(wpath));
-        attrs = GetFileAttributesW(wpath);
-        if (attrs != 0xFFFFFFFF &&
-            ((attrs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)) {
-            (void) wcscat(wpath, L"\\*");
-            dir->handle = FindFirstFileW(wpath, &dir->info);
-            dir->result.d_name[0] = '\0';
-        } else {
-            mg_free(dir);
-            dir = NULL;
-        }
-    }
-
-    return dir;
-}
-
-static int closedir(DIR *dir)
-{
-    int result = 0;
-
-    if (dir != NULL) {
-        if (dir->handle != INVALID_HANDLE_VALUE)
-            result = FindClose(dir->handle) ? 0 : -1;
-
-        mg_free(dir);
-    } else {
-        result = -1;
-        SetLastError(ERROR_BAD_ARGUMENTS);
-    }
-
-    return result;
-}
-
-static struct dirent *readdir(DIR *dir)
-{
-    struct dirent *result = 0;
-
-    if (dir) {
-        if (dir->handle != INVALID_HANDLE_VALUE) {
-            result = &dir->result;
-            (void) WideCharToMultiByte(CP_UTF8, 0,
-                                       dir->info.cFileName, -1, result->d_name,
-                                       sizeof(result->d_name), NULL, NULL);
-
-            if (!FindNextFileW(dir->handle, &dir->info)) {
-                (void) FindClose(dir->handle);
-                dir->handle = INVALID_HANDLE_VALUE;
-            }
-
-        } else {
-            SetLastError(ERROR_FILE_NOT_FOUND);
-        }
-    } else {
-        SetLastError(ERROR_BAD_ARGUMENTS);
-    }
-
-    return result;
-}
-
-#ifndef HAVE_POLL
-static int poll(struct pollfd *pfd, int n, int milliseconds)
-{
-    struct timeval tv;
-    fd_set set;
-    int i, result;
-    SOCKET maxfd = 0;
-
-    tv.tv_sec = milliseconds / 1000;
-    tv.tv_usec = (milliseconds % 1000) * 1000;
-    FD_ZERO(&set);
-
-    for (i = 0; i < n; i++) {
-        FD_SET((SOCKET) pfd[i].fd, &set);
-        pfd[i].revents = 0;
-
-        if (pfd[i].fd > maxfd) {
-            maxfd = pfd[i].fd;
-        }
-    }
-
-    if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) {
-        for (i = 0; i < n; i++) {
-            if (FD_ISSET(pfd[i].fd, &set)) {
-                pfd[i].revents = POLLIN;
-            }
-        }
-    }
-
-    return result;
-}
-#endif /* HAVE_POLL */
-
-static void set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */)
-{
-    (void) conn; /* Unused. */
-    (void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
-}
-
-int mg_start_thread(mg_thread_func_t f, void *p)
-{
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
-    /* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 */
-    return ((_beginthread((void (__cdecl *)(void *)) f, USE_STACK_SIZE, p) == ((uintptr_t)(-1L))) ? -1 : 0);
-#else
-    return ((_beginthread((void (__cdecl *)(void *)) f, 0, p) == ((uintptr_t)(-1L))) ? -1 : 0);
-#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
-}
-
-/* Start a thread storing the thread context. */
-
-static int mg_start_thread_with_id(unsigned (__stdcall *f)(void *), void *p,
-                                   pthread_t *threadidptr)
-{
-    uintptr_t uip;
-    HANDLE threadhandle;
-    int result = -1;
-
-    uip = _beginthreadex(NULL, 0, (unsigned (__stdcall *)(void *)) f, p, 0,
-                         NULL);
-    threadhandle = (HANDLE) uip;
-    if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) {
-        *threadidptr = threadhandle;
-        result = 0;
-    }
-
-    return result;
-}
-
-/* Wait for a thread to finish. */
-
-static int mg_join_thread(pthread_t threadid)
-{
-    int result;
-    DWORD dwevent;
-
-    result = -1;
-    dwevent = WaitForSingleObject(threadid, INFINITE);
-    if (dwevent == WAIT_FAILED) {
-        int err;
-
-        err = GetLastError();
-        DEBUG_TRACE("WaitForSingleObject() failed, error %d", err);
-    } else {
-        if (dwevent == WAIT_OBJECT_0) {
-            CloseHandle(threadid);
-            result = 0;
-        }
-    }
-
-    return result;
-}
-
-static HANDLE dlopen(const char *dll_name, int flags)
-{
-    wchar_t wbuf[PATH_MAX];
-    (void) flags;
-    to_unicode(dll_name, wbuf, ARRAY_SIZE(wbuf));
-    return LoadLibraryW(wbuf);
-}
-
-static int dlclose(void *handle)
-{
-    int result;
-
-    if (FreeLibrary((HMODULE) handle) != 0) {
-        result = 0;
-    } else {
-        result = -1;
-    }
-
-    return result;
-}
-
-#if !defined(NO_CGI)
-#define SIGKILL 0
-static int kill(pid_t pid, int sig_num)
-{
-    (void) TerminateProcess(pid, sig_num);
-    (void) CloseHandle(pid);
-    return 0;
-}
-
-static void trim_trailing_whitespaces(char *s)
-{
-    char *e = s + strlen(s) - 1;
-    while (e > s && isspace(* (unsigned char *) e)) {
-        *e-- = '\0';
-    }
-}
-
-static pid_t spawn_process(struct mg_connection *conn, const char *prog,
-                           char *envblk, char *envp[], int fdin,
-                           int fdout, const char *dir)
-{
-    HANDLE me;
-    char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
-         cmdline[PATH_MAX], buf[PATH_MAX];
-    struct file file = STRUCT_FILE_INITIALIZER;
-    STARTUPINFOA si;
-    PROCESS_INFORMATION pi = { 0 };
-
-    (void) envp;
-
-    memset(&si, 0, sizeof(si));
-    si.cb = sizeof(si);
-
-    /* TODO(lsm): redirect CGI errors to the error log file */
-    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
-    si.wShowWindow = SW_HIDE;
-
-    me = GetCurrentProcess();
-    DuplicateHandle(me, (HANDLE) _get_osfhandle(fdin), me,
-                    &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
-    DuplicateHandle(me, (HANDLE) _get_osfhandle(fdout), me,
-                    &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
-
-    /* If CGI file is a script, try to read the interpreter line */
-    interp = conn->ctx->config[CGI_INTERPRETER];
-    if (interp == NULL) {
-        buf[0] = buf[1] = '\0';
-
-        /* Read the first line of the script into the buffer */
-        snprintf(cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
-        if (mg_fopen(conn, cmdline, "r", &file)) {
-            p = (char *) file.membuf;
-            mg_fgets(buf, sizeof(buf), &file, &p);
-            mg_fclose(&file);
-            buf[sizeof(buf) - 1] = '\0';
-        }
-
-        if (buf[0] == '#' && buf[1] == '!') {
-            trim_trailing_whitespaces(buf + 2);
-        } else {
-            buf[2] = '\0';
-        }
-        interp = buf + 2;
-    }
-
-    if (interp[0] != '\0') {
-        GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL);
-        interp = full_interp;
-    }
-    GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL);
-
-    mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s\"%s\\%s\"",
-                interp, interp[0] == '\0' ? "" : " ", full_dir, prog);
-
-    DEBUG_TRACE("Running [%s]", cmdline);
-    if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
-                       CREATE_NEW_PROCESS_GROUP, envblk, NULL, &si, &pi) == 0) {
-        mg_cry(conn, "%s: CreateProcess(%s): %ld",
-               __func__, cmdline, ERRNO);
-        pi.hProcess = (pid_t) -1;
-    }
-
-    (void) CloseHandle(si.hStdOutput);
-    (void) CloseHandle(si.hStdInput);
-    if (pi.hThread != NULL)
-        (void) CloseHandle(pi.hThread);
-
-    return (pid_t) pi.hProcess;
-}
-#endif /* !NO_CGI */
-
-static int set_non_blocking_mode(SOCKET sock)
-{
-    unsigned long on = 1;
-    return ioctlsocket(sock, FIONBIO, &on);
-}
-
-#else
-static int mg_stat(struct mg_connection *conn, const char *path,
-                   struct file *filep)
-{
-    struct stat st;
-
-    if (!is_file_in_memory(conn, path, filep) && !stat(path, &st)) {
-        filep->size = st.st_size;
-        filep->modification_time = st.st_mtime;
-        filep->is_directory = S_ISDIR(st.st_mode);
-    } else {
-        filep->modification_time = (time_t) 0;
-    }
-
-    return filep->membuf != NULL || filep->modification_time != (time_t) 0;
-}
-
-static void set_close_on_exec(int fd, struct mg_connection *conn /* may be null */)
-{
-    if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
-        if (conn) {
-            mg_cry(conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, strerror(ERRNO));
-        }
-    }
-}
-
-int mg_start_thread(mg_thread_func_t func, void *param)
-{
-    pthread_t thread_id;
-    pthread_attr_t attr;
-    int result;
-
-    (void) pthread_attr_init(&attr);
-    (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
-    /* Compile-time option to control stack size,
-       e.g. -DUSE_STACK_SIZE=16384 */
-    (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
-#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
-
-    result = pthread_create(&thread_id, &attr, func, param);
-    pthread_attr_destroy(&attr);
-
-    return result;
-}
-
-/* Start a thread storing the thread context. */
-
-static int mg_start_thread_with_id(mg_thread_func_t func, void *param, pthread_t *threadidptr)
-{
-    pthread_t thread_id;
-    pthread_attr_t attr;
-    int result;
-
-    (void) pthread_attr_init(&attr);
-
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
-    /* Compile-time option to control stack size,
-       e.g. -DUSE_STACK_SIZE=16384 */
-    (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
-#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */
-
-    result = pthread_create(&thread_id, &attr, func, param);
-    pthread_attr_destroy(&attr);
-    if ((result == 0) && (threadidptr != NULL)) {
-        *threadidptr = thread_id;
-    }
-    return result;
-}
-
-/* Wait for a thread to finish. */
-
-static int mg_join_thread(pthread_t threadid)
-{
-    int result;
-
-    result = pthread_join(threadid, NULL);
-    return result;
-}
-
-#ifndef NO_CGI
-static pid_t spawn_process(struct mg_connection *conn, const char *prog,
-                           char *envblk, char *envp[], int fdin,
-                           int fdout, const char *dir)
-{
-    pid_t pid;
-    const char *interp;
-
-    (void) envblk;
-
-    if ((pid = fork()) == -1) {
-        /* Parent */
-        send_http_error(conn, 500, NULL,
-            "Error: Creating CGI process\nfork(): %s", strerror(ERRNO));
-    } else if (pid == 0) {
-        /* Child */
-        if (chdir(dir) != 0) {
-            mg_cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO));
-        } else if (dup2(fdin, 0) == -1) {
-            mg_cry(conn, "%s: dup2(%d, 0): %s", __func__, fdin, strerror(ERRNO));
-        } else if (dup2(fdout, 1) == -1) {
-            mg_cry(conn, "%s: dup2(%d, 1): %s", __func__, fdout, strerror(ERRNO));
-        } else {
-            /* Not redirecting stderr to stdout, to avoid output being littered
-               with the error messages. */
-            (void) close(fdin);
-            (void) close(fdout);
-
-            /* After exec, all signal handlers are restored to their default
-               values, with one exception of SIGCHLD. According to
-               POSIX.1-2001 and Linux's implementation, SIGCHLD's handler will
-               leave unchanged after exec if it was set to be ignored. Restore
-               it to default action. */
-            signal(SIGCHLD, SIG_DFL);
-
-            interp = conn->ctx->config[CGI_INTERPRETER];
-            if (interp == NULL) {
-                (void) execle(prog, prog, NULL, envp);
-                mg_cry(conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO));
-            } else {
-                (void) execle(interp, interp, prog, NULL, envp);
-                mg_cry(conn, "%s: execle(%s %s): %s", __func__, interp, prog,
-                       strerror(ERRNO));
-            }
-        }
-        exit(EXIT_FAILURE);
-    }
-
-    return pid;
-}
-#endif /* !NO_CGI */
-
-static int set_non_blocking_mode(SOCKET sock)
-{
-    int flags;
-
-    flags = fcntl(sock, F_GETFL, 0);
-    (void) fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-
-    return 0;
-}
-#endif /* _WIN32 */
-
-/* Write data to the IO channel - opened file descriptor, socket or SSL
-   descriptor. Return number of bytes written. */
-static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
-{
-    int64_t sent;
-    int n, k;
-
-    (void) ssl;  /* Get rid of warning */
-    sent = 0;
-    while (sent < len) {
-
-        /* How many bytes we send in this iteration */
-        k = len - sent > INT_MAX ? INT_MAX : (int) (len - sent);
-
-#ifndef NO_SSL
-        if (ssl != NULL) {
-            n = SSL_write(ssl, buf + sent, k);
-        } else
-#endif
-            if (fp != NULL) {
-                n = (int) fwrite(buf + sent, 1, (size_t) k, fp);
-                if (ferror(fp))
-                    n = -1;
-            } else {
-                n = send(sock, buf + sent, (size_t) k, MSG_NOSIGNAL);
-            }
-
-        if (n <= 0)
-            break;
-
-        sent += n;
-    }
-
-    return sent;
-}
-
-/* Read from IO channel - opened file descriptor, socket, or SSL descriptor.
-   Return negative value on error, or number of bytes read on success. */
-static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
-{
-    int nread;
-
-    if (fp != NULL) {
-        /* Use read() instead of fread(), because if we're reading from the
-           CGI pipe, fread() may block until IO buffer is filled up. We cannot
-           afford to block and must pass all read bytes immediately to the
-           client. */
-        nread = read(fileno(fp), buf, (size_t) len);
-#ifndef NO_SSL
-    } else if (conn->ssl != NULL) {
-        nread = SSL_read(conn->ssl, buf, len);
-#endif
-    } else {
-        nread = recv(conn->client.sock, buf, (size_t) len, 0);
-    }
-
-    return conn->ctx->stop_flag ? -1 : nread;
-}
-
-static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
-{
-    int n, nread = 0;
-
-    while (len > 0 && conn->ctx->stop_flag == 0) {
-        n = pull(fp, conn, buf + nread, len);
-        if (n < 0) {
-            nread = n;  /* Propagate the error */
-            break;
-        } else if (n == 0) {
-            break;  /* No more data to read */
-        } else {
-            conn->consumed_content += n;
-            nread += n;
-            len -= n;
-        }
-    }
-
-    return nread;
-}
-
-int mg_read(struct mg_connection *conn, void *buf, size_t len)
-{
-    int64_t n, buffered_len, nread;
-    int64_t len64 = (int64_t)(len > INT_MAX ? INT_MAX : len); /* since the return value is int, we may not read more bytes */
-    const char *body;
-
-    /* If Content-Length is not set for a PUT or POST request, read until socket is closed */
-    if (conn->consumed_content == 0 && conn->content_len == -1) {
-        conn->content_len = INT64_MAX;
-        conn->must_close = 1;
-    }
-
-    nread = 0;
-    if (conn->consumed_content < conn->content_len) {
-        /* Adjust number of bytes to read. */
-        int64_t left_to_read = conn->content_len - conn->consumed_content;
-        if (left_to_read < len64) {
-            /* Do not reade more than the total content length of the request. */
-            len64 = left_to_read;
-        }
-
-        /* Return buffered data */
-        buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len - conn->consumed_content;
-        if (buffered_len > 0) {
-            if (len64 < buffered_len) {
-                buffered_len = len64;
-            }
-            body = conn->buf + conn->request_len + conn->consumed_content;
-            memcpy(buf, body, (size_t) buffered_len);
-            len64 -= buffered_len;
-            conn->consumed_content += buffered_len;
-            nread += buffered_len;
-            buf = (char *) buf + buffered_len;
-        }
-
-        /* We have returned all buffered data. Read new data from the remote
-           socket. */
-        if ((n = pull_all(NULL, conn, (char *) buf, (int)len64)) >= 0) {
-            nread += n;
-        } else {
-            nread = (nread > 0 ? nread : n);
-        }
-    }
-    return (int)nread;
-}
-
-int mg_write(struct mg_connection *conn, const void *buf, size_t len)
-{
-    time_t now;
-    int64_t n, total, allowed;
-
-    if (conn->throttle > 0) {
-        if ((now = time(NULL)) != conn->last_throttle_time) {
-            conn->last_throttle_time = now;
-            conn->last_throttle_bytes = 0;
-        }
-        allowed = conn->throttle - conn->last_throttle_bytes;
-        if (allowed > (int64_t) len) {
-            allowed = len;
-        }
-        if ((total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
-                          (int64_t) allowed)) == allowed) {
-            buf = (char *) buf + total;
-            conn->last_throttle_bytes += total;
-            while (total < (int64_t) len && conn->ctx->stop_flag == 0) {
-                allowed = conn->throttle > (int64_t) len - total ?
-                          (int64_t) len - total : conn->throttle;
-                if ((n = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
-                              (int64_t) allowed)) != allowed) {
-                    break;
-                }
-                sleep(1);
-                conn->last_throttle_bytes = allowed;
-                conn->last_throttle_time = time(NULL);
-                buf = (char *) buf + n;
-                total += n;
-            }
-        }
-    } else {
-        total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
-                     (int64_t) len);
-    }
-    return (int) total;
-}
-
-/* Alternative alloc_vprintf() for non-compliant C runtimes */
-static int alloc_vprintf2(char **buf, const char *fmt, va_list ap)
-{
-    va_list ap_copy;
-    int size = MG_BUF_LEN;
-    int len = -1;
-
-    *buf = NULL;
-    while (len == -1) {
-        if (*buf) mg_free(*buf);
-        *buf = (char *)mg_malloc(size *= 4);
-        if (!*buf) break;
-        va_copy(ap_copy, ap);
-        len = vsnprintf(*buf, size, fmt, ap_copy);
-        va_end(ap_copy);
-    }
-
-    return len;
-}
-
-/* Print message to buffer. If buffer is large enough to hold the message,
-   return buffer. If buffer is to small, allocate large enough buffer on heap,
-   and return allocated buffer. */
-static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap)
-{
-    va_list ap_copy;
-    int len;
-
-    /* Windows is not standard-compliant, and vsnprintf() returns -1 if
-       buffer is too small. Also, older versions of msvcrt.dll do not have
-       _vscprintf().  However, if size is 0, vsnprintf() behaves correctly.
-       Therefore, we make two passes: on first pass, get required message
-       length.
-       On second pass, actually print the message. */
-    va_copy(ap_copy, ap);
-    len = vsnprintf(NULL, 0, fmt, ap_copy);
-    va_end(ap_copy);
-
-    if (len < 0) {
-        /* C runtime is not standard compliant, vsnprintf() returned -1.
-           Switch to alternative code path that uses incremental allocations.
-        */
-        va_copy(ap_copy, ap);
-        len = alloc_vprintf2(buf, fmt, ap);
-        va_end(ap_copy);
-    } else if (len > (int) size &&
-               (size = len + 1) > 0 &&
-               (*buf = (char *) mg_malloc(size)) == NULL) {
-        len = -1;  /* Allocation failed, mark failure */
-    } else {
-        va_copy(ap_copy, ap);
-        IGNORE_UNUSED_RESULT(vsnprintf(*buf, size, fmt, ap_copy));
-        va_end(ap_copy);
-    }
-
-    return len;
-}
-
-int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap)
-{
-    char mem[MG_BUF_LEN], *buf = mem;
-    int len;
-
-    if ((len = alloc_vprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
-        len = mg_write(conn, buf, (size_t) len);
-    }
-    if (buf != mem && buf != NULL) {
-        mg_free(buf);
-    }
-
-    return len;
-}
-
-int mg_printf(struct mg_connection *conn, const char *fmt, ...)
-{
-    va_list ap;
-    int result;
-
-    va_start(ap, fmt);
-    result = mg_vprintf(conn, fmt, ap);
-    va_end(ap);
-
-    return result;
-}
-
-int mg_url_decode(const char *src, int src_len, char *dst,
-                  int dst_len, int is_form_url_encoded)
-{
-    int i, j, a, b;
-#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
-
-    for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
-        if (i < src_len - 2 && src[i] == '%' &&
-            isxdigit(* (const unsigned char *) (src + i + 1)) &&
-            isxdigit(* (const unsigned char *) (src + i + 2))) {
-            a = tolower(* (const unsigned char *) (src + i + 1));
-            b = tolower(* (const unsigned char *) (src + i + 2));
-            dst[j] = (char) ((HEXTOI(a) << 4) | HEXTOI(b));
-            i += 2;
-        } else if (is_form_url_encoded && src[i] == '+') {
-            dst[j] = ' ';
-        } else {
-            dst[j] = src[i];
-        }
-    }
-
-    dst[j] = '\0'; /* Null-terminate the destination */
-
-    return i >= src_len ? j : -1;
-}
-
-int mg_get_var(const char *data, size_t data_len, const char *name,
-               char *dst, size_t dst_len)
-{
-    return mg_get_var2(data,data_len,name,dst,dst_len,0);
-}
-
-int mg_get_var2(const char *data, size_t data_len, const char *name,
-                char *dst, size_t dst_len, size_t occurrence)
-{
-    const char *p, *e, *s;
-    size_t name_len;
-    int len;
-
-    if (dst == NULL || dst_len == 0) {
-        len = -2;
-    } else if (data == NULL || name == NULL || data_len == 0) {
-        len = -1;
-        dst[0] = '\0';
-    } else {
-        name_len = strlen(name);
-        e = data + data_len;
-        len = -1;
-        dst[0] = '\0';
-
-        /* data is "var1=val1&var2=val2...". Find variable first */
-        for (p = data; p + name_len < e; p++) {
-            if ((p == data || p[-1] == '&') && p[name_len] == '=' &&
-                !mg_strncasecmp(name, p, name_len) && 0 == occurrence--) {
-
-                /* Point p to variable value */
-                p += name_len + 1;
-
-                /* Point s to the end of the value */
-                s = (const char *) memchr(p, '&', (size_t)(e - p));
-                if (s == NULL) {
-                    s = e;
-                }
-                assert(s >= p);
-
-                /* Decode variable into destination buffer */
-                len = mg_url_decode(p, (int)(s - p), dst, (int)dst_len, 1);
-
-                /* Redirect error code from -1 to -2 (destination buffer too
-                   small). */
-                if (len == -1) {
-                    len = -2;
-                }
-                break;
-            }
-        }
-    }
-
-    return len;
-}
-
-int mg_get_cookie(const char *cookie_header, const char *var_name,
-                  char *dst, size_t dst_size)
-{
-    const char *s, *p, *end;
-    int name_len, len = -1;
-
-    if (dst == NULL || dst_size == 0) {
-        len = -2;
-    } else if (var_name == NULL || (s = cookie_header) == NULL) {
-        len = -1;
-        dst[0] = '\0';
-    } else {
-        name_len = (int) strlen(var_name);
-        end = s + strlen(s);
-        dst[0] = '\0';
-
-        for (; (s = mg_strcasestr(s, var_name)) != NULL; s += name_len) {
-            

<TRUNCATED>

[11/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/desc.xml
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/desc.xml b/remote_services/discovery_common/src/desc.xml
new file mode 100644
index 0000000..5998992
--- /dev/null
+++ b/remote_services/discovery_common/src/desc.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ -->
+<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
+	<endpoint-description>
+		<property name="service.intents">
+			<list>
+				<value>SOAP</value>
+				<value>HTTP</value>
+			</list>
+		</property>
+		<property name="endpoint.id" value="http://ws.acme.com:9000/hello" />
+		<property name="objectClass" value="com.acme.Foo" />
+		<property name="endpoint.package.version.com.acme" value="4.2" />
+		<property name="service.imported.configs" value="com.acme" />
+		<property name="com.acme.ws.xml">
+			<xml>
+				<config xmlns="http://acme.com/defs">
+					<port>1029</port>
+					<host>www.acme.com</host>
+				</config>
+			</xml>
+		</property>
+	</endpoint-description>
+</endpoint-descriptions>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/discovery.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/discovery.c b/remote_services/discovery_common/src/discovery.c
new file mode 100644
index 0000000..d124c15
--- /dev/null
+++ b/remote_services/discovery_common/src/discovery.c
@@ -0,0 +1,234 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery.c
+ *
+ * \date        Aug 8, 2014
+ * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdbool.h>
+#include <netdb.h>
+#include <string.h>
+
+#include "celix_threads.h"
+#include "bundle_context.h"
+#include "log_helper.h"
+#include "discovery.h"
+#include "endpoint_discovery_server.h"
+#include "discovery_impl.h" //TODO rename impl
+
+
+celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
+	celix_status_t status;
+	discovery_pt discovery = handle;
+
+	logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Endpoint for %s, with filter \"%s\" added...", endpoint->service, matchedFilter);
+
+	status = endpointDiscoveryServer_addEndpoint(discovery->server, endpoint);
+
+	return status;
+}
+
+celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
+	celix_status_t status;
+	discovery_pt discovery = handle;
+
+	logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Endpoint for %s, with filter \"%s\" removed...", endpoint->service, matchedFilter);
+
+	status = endpointDiscoveryServer_removeEndpoint(discovery->server, endpoint);
+
+	return status;
+}
+
+celix_status_t discovery_endpointListenerAdding(void* handle, service_reference_pt reference, void** service) {
+	celix_status_t status = CELIX_SUCCESS;
+	discovery_pt discovery = handle;
+
+	bundleContext_getService(discovery->context, reference, service);
+
+	return status;
+}
+
+celix_status_t discovery_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) {
+	celix_status_t status = CELIX_SUCCESS;
+	discovery_pt discovery = handle;
+
+	const char *discoveryListener = NULL;
+	serviceReference_getProperty(reference, "DISCOVERY", &discoveryListener);
+	const char *scope = NULL;
+	serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+	filter_pt filter = filter_create(scope);
+
+	if (discoveryListener != NULL && strcmp(discoveryListener, "true") == 0) {
+		logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Ignored - Discovery listener");
+	} else {
+		celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+		hash_map_iterator_pt iter = hashMapIterator_create(discovery->discoveredServices);
+		while (hashMapIterator_hasNext(iter)) {
+			endpoint_description_pt endpoint = hashMapIterator_nextValue(iter);
+
+			bool matchResult = false;
+			filter_match(filter, endpoint->properties, &matchResult);
+			if (matchResult) {
+				endpoint_listener_pt listener = service;
+
+				logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Added - Add Scope");
+
+				listener->endpointAdded(listener->handle, endpoint, NULL);
+			}
+		}
+		hashMapIterator_destroy(iter);
+
+		celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+		celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+		hashMap_put(discovery->listenerReferences, reference, NULL);
+
+		celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+	}
+
+	filter_destroy(filter);
+
+	return status;
+}
+
+celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status;
+
+	status = discovery_endpointListenerRemoved(handle, reference, service);
+	if (status == CELIX_SUCCESS) {
+        status = discovery_endpointListenerAdded(handle, reference, service);
+	}
+
+	return status;
+}
+
+celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) {
+    celix_status_t status;
+    discovery_pt discovery = handle;
+
+    status = celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+    if (status == CELIX_SUCCESS) {
+        if (discovery->listenerReferences != NULL) {
+            if (hashMap_remove(discovery->listenerReferences, reference)) {
+                logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
+            }
+        }
+
+        status = celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+    }
+
+	return status;
+}
+
+celix_status_t discovery_informEndpointListeners(discovery_pt discovery, endpoint_description_pt endpoint, bool endpointAdded) {
+	celix_status_t status;
+
+	// Inform listeners of new endpoint
+	status = celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+    if (status == CELIX_SUCCESS) {
+        if (discovery->listenerReferences != NULL) {
+            hash_map_iterator_pt iter = hashMapIterator_create(discovery->listenerReferences);
+            while (hashMapIterator_hasNext(iter)) {
+                hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+                service_reference_pt reference = hashMapEntry_getKey(entry);
+                endpoint_listener_pt listener = NULL;
+
+                const char* scope = NULL;
+                serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+                filter_pt filter = filter_create(scope);
+                bool matchResult = false;
+
+                status = filter_match(filter, endpoint->properties, &matchResult);
+                if (status == CELIX_SUCCESS) {
+                    if (matchResult) {
+                        bundleContext_getService(discovery->context, reference, (void **) &listener);
+                        if (endpointAdded) {
+                            logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Adding service (%s)", endpoint->service);
+
+                            listener->endpointAdded(listener->handle, endpoint, (char*)scope);
+                        } else {
+                            logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Removing service (%s)", endpoint->service);
+
+                            listener->endpointRemoved(listener->handle, endpoint, (char*)scope);
+                        }
+                    }
+
+                    filter_destroy(filter);
+                }
+            }
+            hashMapIterator_destroy(iter);
+        }
+
+        status = celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+    }
+
+	return status;
+}
+
+celix_status_t discovery_addDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+    if (status == CELIX_SUCCESS) {
+        char *endpointId = endpoint->id;
+        bool exists = hashMap_get(discovery->discoveredServices, endpointId) != NULL;
+        if (!exists) {
+            hashMap_put(discovery->discoveredServices, endpointId, endpoint);
+        }
+
+        status = celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+        if (!exists) {
+            // notify our listeners that a new endpoint is available...
+            discovery_informEndpointListeners(discovery, endpoint, true /* addingService */);
+        }
+    }
+
+	return status;
+}
+
+celix_status_t discovery_removeDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+    if (status == CELIX_SUCCESS) {
+        char *endpointId = endpoint->id;
+        void *oldValue = hashMap_remove(discovery->discoveredServices, endpointId);
+
+        status = celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+        if (oldValue) {
+            status = discovery_informEndpointListeners(discovery, endpoint, false /* removeService */);
+        }
+    }
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/discovery_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/discovery_activator.c b/remote_services/discovery_common/src/discovery_activator.c
new file mode 100644
index 0000000..3267d25
--- /dev/null
+++ b/remote_services/discovery_common/src/discovery_activator.c
@@ -0,0 +1,186 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery_activator.c
+ *
+ * \date        Aug 8, 2014
+ * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "bundle_activator.h"
+#include "service_tracker.h"
+#include "constants.h"
+
+#include "log_helper.h"
+#include "discovery.h"
+#include "remote_constants.h"
+
+struct activator {
+	bundle_context_pt context;
+	discovery_pt discovery;
+	log_helper_pt loghelper;
+
+	service_tracker_pt endpointListenerTracker;
+	endpoint_listener_pt endpointListener;
+	service_registration_pt endpointListenerService;
+};
+
+celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) {
+	celix_status_t status;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(activator->discovery, discovery_endpointListenerAdding, discovery_endpointListenerAdded, discovery_endpointListenerModified,
+			discovery_endpointListenerRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker);
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status;
+
+	struct activator* activator = calloc(1,sizeof(struct activator));
+	if (!activator) {
+		return CELIX_ENOMEM;
+	}
+
+	status = discovery_create(context, &activator->discovery);
+	if (status == CELIX_SUCCESS) {
+		activator->context = context;
+
+		logHelper_create(context, &activator->loghelper);
+
+		status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
+		if(status==CELIX_SUCCESS){
+			*userData = activator;
+		}
+		else{
+			bundleActivator_destroy(activator,context);
+		}
+	}
+	else{
+		free(activator);
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status;
+	struct activator *activator = userData;
+	const char *uuid = NULL;
+
+	logHelper_start(activator->loghelper);
+
+	status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+	if (!uuid) {
+		logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "no framework UUID defined?!");
+		return CELIX_ILLEGAL_STATE;
+	}
+
+	size_t len = 11 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
+	char *scope = malloc(len + 1);
+	if (!scope) {
+		return CELIX_ENOMEM;
+	}
+
+	sprintf(scope, "(&(%s=*)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+	scope[len] = 0;
+
+	logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "using scope %s.", scope);
+
+	properties_pt props = properties_create();
+	properties_set(props, "DISCOVERY", "true");
+	properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_open(activator->endpointListenerTracker);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		status = discovery_start(activator->discovery);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		endpoint_listener_pt endpointListener = calloc(1, sizeof(struct endpoint_listener));
+
+		if (endpointListener) {
+			endpointListener->handle = activator->discovery;
+			endpointListener->endpointAdded = discovery_endpointAdded;
+			endpointListener->endpointRemoved = discovery_endpointRemoved;
+
+			status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService);
+
+			if (status == CELIX_SUCCESS) {
+				activator->endpointListener = endpointListener;
+			}
+		}
+	}
+	// We can release the scope, as properties_set makes a copy of the key & value...
+	free(scope);
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status;
+	struct activator *activator = userData;
+
+	status = discovery_stop(activator->discovery);
+
+	status = serviceTracker_close(activator->endpointListenerTracker);
+
+	status = serviceRegistration_unregister(activator->endpointListenerService);
+	free(activator->endpointListener);
+
+	logHelper_stop(activator->loghelper);
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status;
+	struct activator *activator = userData;
+
+	status = serviceTracker_destroy(activator->endpointListenerTracker);
+
+	status = discovery_destroy(activator->discovery);
+
+	logHelper_destroy(&activator->loghelper);
+
+	activator->loghelper = NULL;
+	activator->endpointListenerTracker = NULL;
+	activator->endpointListenerService = NULL;
+	activator->discovery = NULL;
+	activator->context = NULL;
+
+	free(activator);
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/endpoint_descriptor_reader.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_descriptor_reader.c b/remote_services/discovery_common/src/endpoint_descriptor_reader.c
new file mode 100644
index 0000000..ea176bf
--- /dev/null
+++ b/remote_services/discovery_common/src/endpoint_descriptor_reader.c
@@ -0,0 +1,387 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_descriptor_reader.c
+ *
+ *  \date       24 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#include <stdbool.h>
+#include <string.h>
+#include <libxml/xmlreader.h>
+
+#include "log_helper.h"
+#include "remote_constants.h"
+
+#include "endpoint_description.h"
+#include "endpoint_descriptor_common.h"
+#include "endpoint_descriptor_reader.h"
+
+struct endpoint_descriptor_reader {
+    xmlTextReaderPtr reader;
+    log_helper_pt* loghelper;
+};
+
+static valueType valueTypeFromString(char *name);
+
+celix_status_t endpointDescriptorReader_create(endpoint_discovery_poller_pt poller, endpoint_descriptor_reader_pt *reader) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *reader = malloc(sizeof(**reader));
+    if (!*reader) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*reader)->reader = NULL;
+        (*reader)->loghelper = poller->loghelper;
+    }
+
+    return status;
+}
+
+celix_status_t endpointDescriptorReader_destroy(endpoint_descriptor_reader_pt reader) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    reader->loghelper = NULL;
+
+    free(reader);
+
+    return status;
+}
+
+void endpointDescriptorReader_addSingleValuedProperty(properties_pt properties, const xmlChar* name, const xmlChar* value) {
+	properties_set(properties, (char *) name, (char*) value);
+}
+
+void endpointDescriptorReader_addMultiValuedProperty(properties_pt properties, const xmlChar* name, array_list_pt values) {
+	char *value = calloc(256, sizeof(*value));
+	if (value) {
+		unsigned int size = arrayList_size(values);
+        unsigned int i;
+        for (i = 0; i < size; i++) {
+			char* item = (char*) arrayList_get(values, i);
+			if (i > 0) {
+				value = strcat(value, ",");
+			}
+			value = strcat(value, item);
+		}
+
+		properties_set(properties, (char *) name, value);
+
+		free(value);
+	}
+}
+
+celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_pt reader, char *document, array_list_pt *endpoints) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    reader->reader = xmlReaderForMemory(document, (int) strlen(document), NULL, "UTF-8", 0);
+    if (reader->reader == NULL) {
+        status = CELIX_BUNDLE_EXCEPTION;
+    } else {
+        bool inProperty = false;
+        bool inXml = false;
+        bool inArray = false;
+        bool inList = false;
+        bool inSet = false;
+        bool inValue = false;
+
+        const xmlChar *propertyName = NULL;
+        const xmlChar *propertyValue = NULL;
+        valueType propertyType = VALUE_TYPE_STRING;
+        xmlChar *valueBuffer = xmlMalloc(256);
+        valueBuffer[0] = '\0';
+
+        array_list_pt propertyValues = NULL;
+        arrayList_create(&propertyValues);
+
+        array_list_pt endpointDescriptions = NULL;
+        if (*endpoints) {
+        	// use the given arraylist...
+        	endpointDescriptions = *endpoints;
+        } else {
+			arrayList_create(&endpointDescriptions);
+			// return the read endpoints...
+			*endpoints = endpointDescriptions;
+        }
+
+        properties_pt endpointProperties = NULL;
+
+        int read = xmlTextReaderRead(reader->reader);
+        while (read == XML_TEXTREADER_MODE_INTERACTIVE) {
+            int type = xmlTextReaderNodeType(reader->reader);
+
+            if (type == XML_READER_TYPE_ELEMENT) {
+                const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
+
+                if (inXml) {
+                    valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "<");
+                    valueBuffer = xmlStrcat(valueBuffer, localname);
+
+                    int i = xmlTextReaderMoveToFirstAttribute(reader->reader);
+                    while (i == 1) {
+                        const xmlChar *name = xmlTextReaderConstName(reader->reader);
+                        const xmlChar *value = xmlTextReaderConstValue(reader->reader);
+
+                        valueBuffer = xmlStrcat(valueBuffer, BAD_CAST " ");
+                        valueBuffer = xmlStrcat(valueBuffer, name);
+                        valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "=\"");
+                        valueBuffer = xmlStrcat(valueBuffer, BAD_CAST value);
+                        valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "\"");
+
+                        i = xmlTextReaderMoveToNextAttribute(reader->reader);
+                    }
+
+                    valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
+                } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
+
+                	if (endpointProperties != NULL)
+                		properties_destroy(endpointProperties);
+
+                    endpointProperties = properties_create();
+                } else if (xmlStrcmp(localname, PROPERTY) == 0) {
+                    inProperty = true;
+
+                    propertyName = xmlTextReaderGetAttribute(reader->reader, NAME);
+                    propertyValue = xmlTextReaderGetAttribute(reader->reader, VALUE);
+                    xmlChar *vtype = xmlTextReaderGetAttribute(reader->reader, VALUE_TYPE);
+                    propertyType = valueTypeFromString((char*) vtype);
+                    arrayList_clear(propertyValues);
+
+                    if (xmlTextReaderIsEmptyElement(reader->reader)) {
+                        inProperty = false;
+
+                        if (propertyValue != NULL) {
+                        	endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
+                        }
+
+                        xmlFree((void *) propertyName);
+                        xmlFree((void *) propertyValue);
+                        xmlFree((void *) vtype);
+                    }
+                } else {
+                    valueBuffer[0] = 0;
+                    inArray |= inProperty && xmlStrcmp(localname, ARRAY) == 0;
+                    inList |= inProperty && xmlStrcmp(localname, LIST) == 0;
+                    inSet |= inProperty && xmlStrcmp(localname, SET) == 0;
+                    inXml |= inProperty && xmlStrcmp(localname, XML) == 0;
+                    inValue |= inProperty && xmlStrcmp(localname, VALUE) == 0;
+				}
+			} else if (type == XML_READER_TYPE_END_ELEMENT) {
+				const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
+
+                if (inXml) {
+                    if (xmlStrcmp(localname, XML) != 0)  {
+                    	valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "</");
+                    	valueBuffer = xmlStrcat(valueBuffer, localname);
+                    	valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
+                    }
+                    else {
+                        inXml = false;
+                    }
+                } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
+                    endpoint_description_pt endpointDescription = NULL;
+                    // Completely parsed endpoint description, add it to our list of results...
+                    if(endpointDescription_create(endpointProperties, &endpointDescription) == CELIX_SUCCESS){
+			arrayList_add(endpointDescriptions, endpointDescription);
+                    }
+
+                    endpointProperties = properties_create();
+                } else if (xmlStrcmp(localname, PROPERTY) == 0) {
+                    inProperty = false;
+
+                    if (inArray || inList || inSet) {
+						endpointDescriptorReader_addMultiValuedProperty(endpointProperties, propertyName, propertyValues);
+                    }
+                    else if (propertyValue != NULL) {
+                    	if (propertyType != VALUE_TYPE_STRING) {
+                    		logHelper_log(*reader->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_DESCRIPTOR_READER: Only string support for %s\n", propertyName);
+                    	}
+                    	endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
+
+                        xmlFree((void *) propertyValue);
+                    }
+                    else {
+                    	endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, valueBuffer);
+                    }
+
+                    xmlFree((void *) propertyName);
+					unsigned int k=0;
+					for(;k<arrayList_size(propertyValues);k++){
+						free(arrayList_get(propertyValues,k));
+					}
+                    arrayList_clear(propertyValues);
+
+                    propertyType = VALUE_TYPE_STRING;
+                    inArray = false;
+                    inList = false;
+                    inSet = false;
+                    inXml = false;
+                } else if (xmlStrcmp(localname, VALUE) == 0) {
+                    arrayList_add(propertyValues, strdup((char*) valueBuffer));
+                    valueBuffer[0] = 0;
+                    inValue = false;
+                }
+            } else if (type == XML_READER_TYPE_TEXT) {
+                if (inValue || inXml) {
+                    const xmlChar *value = xmlTextReaderValue(reader->reader);
+                    valueBuffer = xmlStrcat(valueBuffer, value);
+                    xmlFree((void *)value);
+                }
+            }
+
+            read = xmlTextReaderRead(reader->reader);
+        }
+
+		if(endpointProperties!=NULL){
+			properties_destroy(endpointProperties);
+		}
+
+		unsigned int k=0;
+		for(;k<arrayList_size(propertyValues);k++){
+			free(arrayList_get(propertyValues,k));
+		}
+        arrayList_destroy(propertyValues);
+        xmlFree(valueBuffer);
+
+        xmlFreeTextReader(reader->reader);
+    }
+
+    return status;
+}
+
+static valueType valueTypeFromString(char *name) {
+    if (name == NULL || strcmp(name, "") == 0 || strcmp(name, "String") == 0) {
+        return VALUE_TYPE_STRING;
+    } else if (strcmp(name, "long") == 0 || strcmp(name, "Long") == 0) {
+        return VALUE_TYPE_LONG;
+    } else if (strcmp(name, "double") == 0 || strcmp(name, "Double") == 0) {
+        return VALUE_TYPE_DOUBLE;
+    } else if (strcmp(name, "float") == 0 || strcmp(name, "Float") == 0) {
+        return VALUE_TYPE_FLOAT;
+    } else if (strcmp(name, "int") == 0 || strcmp(name, "integer") == 0 || strcmp(name, "Integer") == 0) {
+        return VALUE_TYPE_INTEGER;
+    } else if (strcmp(name, "short") == 0 || strcmp(name, "Short") == 0) {
+        return VALUE_TYPE_SHORT;
+    } else if (strcmp(name, "byte") == 0 || strcmp(name, "Byte") == 0) {
+        return VALUE_TYPE_BYTE;
+    } else if (strcmp(name, "char") == 0 || strcmp(name, "Character") == 0) {
+        return VALUE_TYPE_CHAR;
+    } else if (strcmp(name, "boolean") == 0 || strcmp(name, "Boolean") == 0) {
+        return VALUE_TYPE_BOOLEAN;
+    } else {
+        return VALUE_TYPE_STRING;
+    }
+}
+
+#ifdef RSA_ENDPOINT_TEST_READER
+int main() {
+    array_list_pt list = NULL;
+    endpoint_descriptor_reader_pt reader = NULL;
+
+    char *doc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+"<endpoint-descriptions xmlns=\"http://www.osgi.org/xmlns/rsa/v1.0.0\">"
+    "<endpoint-description>"
+    	"<property name=\"endpoint.service.id\" value-type=\"long\" value=\"6\"/>"
+		"<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
+        "<property name=\"service.intents\">"
+            "<list>"
+                "<value>SOAP</value>"
+                "<value>HTTP</value>"
+            "</list>"
+        "</property>"
+        "<property name=\"endpoint.id\" value=\"11111111-1111-1111-1111-111111111111\" />"
+        "<property name=\"objectClass\"><array><value>com.acme.Foo</value></array></property>"
+        "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
+        "<property name=\"service.imported.configs\" value=\"com.acme\" />"
+    	"<property name=\"service.imported\" value=\"true\"/>"
+        "<property name=\"com.acme.ws.xml\">"
+            "<xml>"
+                "<config xmlns=\"http://acme.com/defs\">"
+                    "<port>1029</port>"
+                    "<host>www.acme.com</host>"
+                "</config>"
+            "</xml>"
+        "</property>"
+    "</endpoint-description>"
+		"<endpoint-description>"
+        	"<property name=\"endpoint.service.id\" value-type=\"long\" value=\"5\"/>"
+    		"<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
+			"<property name=\"service.intents\">"
+				"<list>"
+					"<value>SOAP</value>"
+					"<value>HTTP</value>"
+				"</list>"
+			"</property>"
+			"<property name=\"endpoint.id\" value=\"22222222-2222-2222-2222-222222222222\" />"
+            "<property name=\"objectClass\"><array><value>com.acme.Bar</value></array></property>"
+			"<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
+			"<property name=\"service.imported.configs\" value=\"com.acme\" />"
+			"<property name=\"com.acme.ws.xml\">"
+				"<xml>"
+					"<config xmlns=\"http://acme.com/defs\">"
+						"<port>1029</port>"
+						"<host>www.acme.com</host>"
+					"</config>"
+				"</xml>"
+			"</property>"
+		"</endpoint-description>"
+	"</endpoint-descriptions>";
+
+	endpointDescriptorReader_create(&reader);
+
+	endpointDescriptorReader_parseDocument(reader, doc, &list);
+
+	int i;
+	for (i = 0; i < arrayList_size(list); i++) {
+		printf("\nEndpoint description #%d:\n", (i+1));
+		endpoint_description_pt edp = arrayList_get(list, i);
+		printf("Id: %s\n", edp->id);
+		printf("Service Id: %lu\n", edp->serviceId);
+		printf("Framework UUID: %s\n", edp->frameworkUUID);
+		printf("Service: %s\n", edp->service);
+
+		properties_pt props = edp->properties;
+		if (props) {
+			printf("Service properties:\n");
+			hash_map_iterator_pt iter = hashMapIterator_create(props);
+			while (hashMapIterator_hasNext(iter)) {
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+				printf("- %s => '%s'\n", hashMapEntry_getKey(entry), hashMapEntry_getValue(entry));
+			}
+			hashMapIterator_destroy(iter);
+		} else {
+			printf("No service properties...\n");
+		}
+
+
+		endpointDescription_destroy(edp);
+	}
+
+	if (list != NULL) {
+		arrayList_destroy(list);
+	}
+
+	endpointDescriptorReader_destroy(reader);
+
+    return 0;
+}
+#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/endpoint_descriptor_writer.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_descriptor_writer.c b/remote_services/discovery_common/src/endpoint_descriptor_writer.c
new file mode 100644
index 0000000..71b07b4
--- /dev/null
+++ b/remote_services/discovery_common/src/endpoint_descriptor_writer.c
@@ -0,0 +1,233 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_descriptor_writer.c
+ *
+ *  \date       26 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/xmlwriter.h>
+
+#include "constants.h"
+#include "remote_constants.h"
+
+#include "endpoint_description.h"
+#include "endpoint_descriptor_common.h"
+#include "endpoint_descriptor_writer.h"
+
+struct endpoint_descriptor_writer {
+    xmlBufferPtr buffer;
+    xmlTextWriterPtr writer;
+};
+
+static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint);
+
+static char* valueTypeToString(valueType type);
+
+celix_status_t endpointDescriptorWriter_create(endpoint_descriptor_writer_pt *writer) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *writer = malloc(sizeof(**writer));
+    if (!*writer) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*writer)->buffer = xmlBufferCreate();
+        if ((*writer)->buffer == NULL) {
+            status = CELIX_BUNDLE_EXCEPTION;
+        } else {
+            (*writer)->writer = xmlNewTextWriterMemory((*writer)->buffer, 0);
+            if ((*writer)->writer == NULL) {
+                status = CELIX_BUNDLE_EXCEPTION;
+            }
+        }
+    }
+
+    return status;
+}
+
+celix_status_t endpointDescriptorWriter_destroy(endpoint_descriptor_writer_pt writer) {
+    xmlFreeTextWriter(writer->writer);
+    xmlBufferFree(writer->buffer);
+    free(writer);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t endpointDescriptorWriter_writeDocument(endpoint_descriptor_writer_pt writer, array_list_pt endpoints, char **document) {
+    celix_status_t status = CELIX_SUCCESS;
+    int rc;
+
+    rc = xmlTextWriterStartDocument(writer->writer, NULL, "UTF-8", NULL);
+    if (rc < 0) {
+        status = CELIX_BUNDLE_EXCEPTION;
+    } else {
+        rc = xmlTextWriterStartElementNS(writer->writer, NULL, ENDPOINT_DESCRIPTIONS, XMLNS);
+        if (rc < 0) {
+            status = CELIX_BUNDLE_EXCEPTION;
+        } else {
+            unsigned int i;
+            for (i = 0; i < arrayList_size(endpoints); i++) {
+                endpoint_description_pt endpoint = arrayList_get(endpoints, i);
+                status = endpointDescriptorWriter_writeEndpoint(writer, endpoint);
+            }
+            if (status == CELIX_SUCCESS) {
+                rc = xmlTextWriterEndElement(writer->writer);
+                if (rc < 0) {
+                    status = CELIX_BUNDLE_EXCEPTION;
+                } else {
+                    rc = xmlTextWriterEndDocument(writer->writer);
+                    if (rc < 0) {
+                        status = CELIX_BUNDLE_EXCEPTION;
+                    } else {
+                        *document = (char *) writer->buffer->content;
+                    }
+                }
+            }
+        }
+    }
+
+    return status;
+}
+
+static celix_status_t endpointDescriptorWriter_writeArrayValue(xmlTextWriterPtr writer, const xmlChar* value) {
+    xmlTextWriterStartElement(writer, ARRAY);
+    xmlTextWriterStartElement(writer, VALUE);
+    xmlTextWriterWriteString(writer, value);
+    xmlTextWriterEndElement(writer); // value
+    xmlTextWriterEndElement(writer); // array
+
+	return CELIX_SUCCESS;
+}
+
+static celix_status_t endpointDescriptorWriter_writeTypedValue(xmlTextWriterPtr writer, valueType type, const xmlChar* value) {
+	xmlTextWriterWriteAttribute(writer, VALUE_TYPE, (const xmlChar*) valueTypeToString(type));
+	xmlTextWriterWriteAttribute(writer, VALUE, value);
+
+	return CELIX_SUCCESS;
+}
+
+static celix_status_t endpointDescriptorWriter_writeUntypedValue(xmlTextWriterPtr writer, const xmlChar* value) {
+	xmlTextWriterWriteAttribute(writer, VALUE, value);
+
+	return CELIX_SUCCESS;
+}
+
+static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (endpoint == NULL || writer == NULL) {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    } else {
+        xmlTextWriterStartElement(writer->writer, ENDPOINT_DESCRIPTION);
+
+        hash_map_iterator_pt iter = hashMapIterator_create(endpoint->properties);
+        while (hashMapIterator_hasNext(iter)) {
+            hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+            void* propertyName = hashMapEntry_getKey(entry);
+			const xmlChar* propertyValue = (const xmlChar*) hashMapEntry_getValue(entry);
+
+            xmlTextWriterStartElement(writer->writer, PROPERTY);
+            xmlTextWriterWriteAttribute(writer->writer, NAME, propertyName);
+
+            if (strcmp(OSGI_FRAMEWORK_OBJECTCLASS, (char*) propertyName) == 0) {
+            	// objectClass *must* be represented as array of string values...
+            	endpointDescriptorWriter_writeArrayValue(writer->writer, propertyValue);
+            } else if (strcmp(OSGI_RSA_ENDPOINT_SERVICE_ID, (char*) propertyName) == 0) {
+            	// endpoint.service.id *must* be represented as long value...
+            	endpointDescriptorWriter_writeTypedValue(writer->writer, VALUE_TYPE_LONG, propertyValue);
+            } else {
+            	// represent all other values as plain string values...
+            	endpointDescriptorWriter_writeUntypedValue(writer->writer, propertyValue);
+            }
+
+            xmlTextWriterEndElement(writer->writer);
+        }
+        hashMapIterator_destroy(iter);
+
+        xmlTextWriterEndElement(writer->writer);
+    }
+
+    return status;
+}
+
+
+static char* valueTypeToString(valueType type) {
+	switch (type) {
+		case VALUE_TYPE_BOOLEAN:
+			return "boolean";
+		case VALUE_TYPE_BYTE:
+			return "byte";
+		case VALUE_TYPE_CHAR:
+			return "char";
+		case VALUE_TYPE_DOUBLE:
+			return "double";
+		case VALUE_TYPE_FLOAT:
+			return "float";
+		case VALUE_TYPE_INTEGER:
+			return "int";
+		case VALUE_TYPE_LONG:
+			return "long";
+		case VALUE_TYPE_SHORT:
+			return "short";
+		case VALUE_TYPE_STRING:
+			// FALL-THROUGH!
+		default:
+			return "string";
+	}
+}
+
+#ifdef RSA_ENDPOINT_TEST_WRITER
+int main() {
+    endpoint_descriptor_writer_pt writer = NULL;
+    endpointDescriptorWriter_create(&writer);
+    array_list_pt list = NULL;
+    arrayList_create(&list);
+
+    properties_pt props = properties_create();
+    properties_set(props, "objectClass", "com.acme.Foo");
+    properties_set(props, "endpoint.service.id", "3");
+    properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
+    properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
+    endpoint_description_pt epd = NULL;
+    endpointDescription_create(props, &epd);
+    arrayList_add(list, epd);
+
+    properties_pt props2 = properties_create();
+    properties_set(props2, "objectClass", "com.acme.Bar");
+    properties_set(props, "endpoint.service.id", "4");
+    properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
+    properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
+    endpoint_description_pt epd2 = NULL;
+    endpointDescription_create(props2, &epd2);
+    arrayList_add(list, epd2);
+
+    char *buffer = NULL;
+    endpointDescriptorWriter_writeDocument(writer, list, &buffer);
+
+    arrayList_destroy(list);
+    endpointDescription_destroy(epd);
+    endpointDescription_destroy(epd2);
+    endpointDescriptorWriter_destroy(writer);
+
+    printf("%s\n", buffer);
+}
+#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/endpoint_discovery_poller.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_discovery_poller.c b/remote_services/discovery_common/src/endpoint_discovery_poller.c
new file mode 100644
index 0000000..73fb7ba
--- /dev/null
+++ b/remote_services/discovery_common/src/endpoint_discovery_poller.c
@@ -0,0 +1,403 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_discovery_poller.c
+ *
+ * \date       3 Jul 2014
+ * \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright  Apache License, Version 2.0
+ */
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <curl/curl.h>
+
+#include "bundle_context.h"
+#include "log_helper.h"
+#include "utils.h"
+
+#include "discovery_impl.h"
+
+#include "endpoint_descriptor_reader.h"
+
+
+#define DISCOVERY_POLL_INTERVAL "DISCOVERY_CFG_POLL_INTERVAL"
+#define DEFAULT_POLL_INTERVAL "10"
+
+
+static void *endpointDiscoveryPoller_performPeriodicPoll(void *data);
+celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints);
+static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints);
+static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals);
+
+/**
+ * Allocates memory and initializes a new endpoint_discovery_poller instance.
+ */
+celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller) {
+	celix_status_t status;
+
+	*poller = malloc(sizeof(struct endpoint_discovery_poller));
+	if (!*poller) {
+		return CELIX_ENOMEM;
+	}
+
+	(*poller)->loghelper = &discovery->loghelper;
+
+	status = celixThreadMutex_create(&(*poller)->pollerLock, NULL);
+	if (status != CELIX_SUCCESS) {
+		return status;
+	}
+
+	const char* interval = NULL;
+	status = bundleContext_getProperty(context, DISCOVERY_POLL_INTERVAL, &interval);
+	if (!interval) {
+		interval = DEFAULT_POLL_INTERVAL;
+	}
+
+	const char* endpointsProp = NULL;
+	status = bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS, &endpointsProp);
+	if (!endpointsProp) {
+		endpointsProp = DEFAULT_POLL_ENDPOINTS;
+	}
+	// we're going to mutate the string with strtok, so create a copy...
+	char* endpoints = strdup(endpointsProp);
+
+	(*poller)->poll_interval = atoi(interval);
+	(*poller)->discovery = discovery;
+	(*poller)->running = false;
+	(*poller)->entries = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+	const char* sep = ",";
+	char *save_ptr = NULL;
+	char* tok = strtok_r(endpoints, sep, &save_ptr);
+	while (tok) {
+		endpointDiscoveryPoller_addDiscoveryEndpoint(*poller, utils_stringTrim(tok));
+		tok = strtok_r(NULL, sep, &save_ptr);
+	}
+	// Clean up after ourselves...
+	free(endpoints);
+
+	status = celixThreadMutex_lock(&(*poller)->pollerLock);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	(*poller)->running = true;
+
+	status += celixThread_create(&(*poller)->pollerThread, NULL, endpointDiscoveryPoller_performPeriodicPoll, *poller);
+	status += celixThreadMutex_unlock(&(*poller)->pollerLock);
+
+	if(status != CELIX_SUCCESS){
+		status = CELIX_BUNDLE_EXCEPTION;
+	}
+
+	return status;
+}
+
+/**
+ * Destroys and frees up memory for a given endpoint_discovery_poller struct.
+ */
+celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller) {
+	celix_status_t status;
+
+	poller->running = false;
+
+	celixThread_join(poller->pollerThread, NULL);
+
+	hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
+	while (hashMapIterator_hasNext(iterator)) {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
+
+		if ( endpointDiscoveryPoller_removeDiscoveryEndpoint(poller, (char*) hashMapEntry_getKey(entry)) == CELIX_SUCCESS) {
+			hashMapIterator_destroy(iterator);
+			iterator = hashMapIterator_create(poller->entries);
+		}
+	}
+	hashMapIterator_destroy(iterator);
+
+	status = celixThreadMutex_lock(&poller->pollerLock);
+
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	hashMap_destroy(poller->entries, true, false);
+
+	status = celixThreadMutex_unlock(&poller->pollerLock);
+
+	poller->loghelper = NULL;
+
+	free(poller);
+
+	return status;
+}
+
+
+celix_status_t endpointDiscoveryPoller_getDiscoveryEndpoints(endpoint_discovery_poller_pt poller, array_list_pt urls) {
+	celixThreadMutex_lock(&(poller)->pollerLock);
+
+	hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
+
+	while(hashMapIterator_hasNext(iterator))  {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
+		char* toAdd = strdup((char*) hashMapEntry_getKey(entry));
+		arrayList_add(urls, toAdd);
+	}
+
+	hashMapIterator_destroy(iterator);
+
+	celixThreadMutex_unlock(&(poller)->pollerLock);
+
+	return CELIX_SUCCESS;
+}
+
+/**
+ * Adds a new endpoint URL to the list of polled endpoints.
+ */
+celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&(poller)->pollerLock);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	// Avoid memory leaks when adding an already existing URL...
+	array_list_pt endpoints = hashMap_get(poller->entries, url);
+	if (endpoints == NULL) {
+		status = arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &endpoints);
+
+		if (status == CELIX_SUCCESS) {
+			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: add new discovery endpoint with url %s", url);
+			hashMap_put(poller->entries, strdup(url), endpoints);
+			endpointDiscoveryPoller_poll(poller, url, endpoints);
+		}
+	}
+
+	status = celixThreadMutex_unlock(&poller->pollerLock);
+
+	return status;
+}
+
+/**
+ * Removes an endpoint URL from the list of polled endpoints.
+ */
+celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (celixThreadMutex_lock(&poller->pollerLock) != CELIX_SUCCESS) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	} else {
+		hash_map_entry_pt entry = hashMap_getEntry(poller->entries, url);
+
+		if (entry == NULL) {
+			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: There was no entry found belonging to url %s - maybe already removed?", url);
+		} else {
+			char* origKey = hashMapEntry_getKey(entry);
+
+			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: remove discovery endpoint with url %s", url);
+
+			array_list_pt entries = hashMap_remove(poller->entries, url);
+
+			if (entries != NULL) {
+				for (unsigned int i = arrayList_size(entries); i > 0; i--) {
+					endpoint_description_pt endpoint = arrayList_get(entries, i - 1);
+					discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
+					arrayList_remove(entries, i - 1);
+					endpointDescription_destroy(endpoint);
+				}
+				arrayList_destroy(entries);
+			}
+
+			free(origKey);
+		}
+		status = celixThreadMutex_unlock(&poller->pollerLock);
+	}
+
+	return status;
+}
+
+
+
+
+celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints) {
+	celix_status_t status;
+	array_list_pt updatedEndpoints = NULL;
+
+	// create an arraylist with a custom equality test to ensure we can find endpoints properly...
+	arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &updatedEndpoints);
+	status = endpointDiscoveryPoller_getEndpoints(poller, url, &updatedEndpoints);
+
+	if (status == CELIX_SUCCESS) {
+		if (updatedEndpoints!=NULL) {
+			for (unsigned int i = arrayList_size(currentEndpoints); i > 0; i--) {
+				endpoint_description_pt endpoint = arrayList_get(currentEndpoints, i - 1);
+
+				if (!arrayList_contains(updatedEndpoints, endpoint)) {
+					status = discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
+					arrayList_remove(currentEndpoints, i - 1);
+					endpointDescription_destroy(endpoint);
+				}
+			}
+
+			for (int i = arrayList_size(updatedEndpoints); i > 0; i--) {
+				endpoint_description_pt endpoint = arrayList_remove(updatedEndpoints, 0);
+
+				if (!arrayList_contains(currentEndpoints, endpoint)) {
+					arrayList_add(currentEndpoints, endpoint);
+					status = discovery_addDiscoveredEndpoint(poller->discovery, endpoint);
+				} else {
+					endpointDescription_destroy(endpoint);
+
+				}
+			}
+		}
+	}
+
+	if(updatedEndpoints!=NULL){
+		arrayList_destroy(updatedEndpoints);
+	}
+
+	return status;
+}
+
+static void *endpointDiscoveryPoller_performPeriodicPoll(void *data) {
+	endpoint_discovery_poller_pt poller = (endpoint_discovery_poller_pt) data;
+
+	useconds_t interval = (useconds_t) (poller->poll_interval * 1000000L);
+
+	while (poller->running) {
+		usleep(interval);
+		celix_status_t status = celixThreadMutex_lock(&poller->pollerLock);
+
+		if (status != CELIX_SUCCESS) {
+			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to obtain lock; retrying...");
+		} else {
+			hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
+
+			while (hashMapIterator_hasNext(iterator)) {
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
+
+				char *url = hashMapEntry_getKey(entry);
+				array_list_pt currentEndpoints = hashMapEntry_getValue(entry);
+
+				endpointDiscoveryPoller_poll(poller, url, currentEndpoints);
+			}
+
+			hashMapIterator_destroy(iterator);
+		}
+
+		status = celixThreadMutex_unlock(&poller->pollerLock);
+		if (status != CELIX_SUCCESS) {
+			logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to release lock; retrying...");
+		}
+	}
+
+	return NULL;
+}
+
+
+
+struct MemoryStruct {
+	char *memory;
+	size_t size;
+};
+
+static size_t endpointDiscoveryPoller_writeMemory(void *contents, size_t size, size_t nmemb, void *memoryPtr) {
+	size_t realsize = size * nmemb;
+	struct MemoryStruct *mem = (struct MemoryStruct *)memoryPtr;
+
+	mem->memory = realloc(mem->memory, mem->size + realsize + 1);
+	if(mem->memory == NULL) {
+		printf("ENDPOINT_POLLER: not enough memory (realloc returned NULL)!");
+		return 0;
+	}
+
+	memcpy(&(mem->memory[mem->size]), contents, realsize);
+	mem->size += realsize;
+	mem->memory[mem->size] = 0;
+
+	return realsize;
+}
+
+static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints) {
+	celix_status_t status = CELIX_SUCCESS;
+
+
+	CURL *curl = NULL;
+	CURLcode res = CURLE_OK;
+
+	struct MemoryStruct chunk;
+	chunk.memory = malloc(1);
+	chunk.size = 0;
+
+	curl = curl_easy_init();
+	if (!curl) {
+		status = CELIX_ILLEGAL_STATE;
+	} else {
+		curl_easy_setopt(curl, CURLOPT_URL, url);
+		curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, endpointDiscoveryPoller_writeMemory);
+		curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L);
+		curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
+		res = curl_easy_perform(curl);
+
+		curl_easy_cleanup(curl);
+	}
+
+	// process endpoints file
+	if (res == CURLE_OK) {
+		endpoint_descriptor_reader_pt reader = NULL;
+
+		status = endpointDescriptorReader_create(poller, &reader);
+		if (status == CELIX_SUCCESS) {
+			status = endpointDescriptorReader_parseDocument(reader, chunk.memory, updatedEndpoints);
+		}
+
+		if (reader) {
+			endpointDescriptorReader_destroy(reader);
+		}
+	} else {
+		logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_ERROR, "ENDPOINT_POLLER: unable to read endpoints from %s, reason: %s", url, curl_easy_strerror(res));
+	}
+
+	// clean up endpoints file
+	if (chunk.memory) {
+		free(chunk.memory);
+	}
+
+	return status;
+}
+
+static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals) {
+	endpoint_description_pt endpoint = (endpoint_description_pt) endpointPtr;
+	endpoint_description_pt compare = (endpoint_description_pt) comparePtr;
+
+	if (strcmp(endpoint->id, compare->id) == 0) {
+		*equals = true;
+	} else {
+		*equals = false;
+	}
+
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/endpoint_discovery_server.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_discovery_server.c b/remote_services/discovery_common/src/endpoint_discovery_server.c
new file mode 100644
index 0000000..f5f82af
--- /dev/null
+++ b/remote_services/discovery_common/src/endpoint_discovery_server.c
@@ -0,0 +1,450 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_discovery_server.c
+ *
+ * \date		Aug 12, 2014
+ * \author		<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#ifndef ANDROID
+#include <ifaddrs.h>
+#endif
+#include "civetweb.h"
+#include "celix_errno.h"
+#include "utils.h"
+#include "log_helper.h"
+#include "discovery.h"
+#include "discovery_impl.h"
+
+#include "endpoint_descriptor_writer.h"
+
+// defines how often the webserver is restarted (with an increased port number)
+#define MAX_NUMBER_OF_RESTARTS 	15
+#define DEFAULT_SERVER_THREADS "1"
+
+#define CIVETWEB_REQUEST_NOT_HANDLED 0
+#define CIVETWEB_REQUEST_HANDLED 1
+
+static const char *response_headers =
+		"HTTP/1.1 200 OK\r\n"
+		"Cache: no-cache\r\n"
+		"Content-Type: application/xml;charset=utf-8\r\n"
+		"\r\n";
+
+struct endpoint_discovery_server {
+	log_helper_pt* loghelper;
+	hash_map_pt entries; // key = endpointId, value = endpoint_descriptor_pt
+
+	celix_thread_mutex_t serverLock;
+
+	const char* path;
+	const char *port;
+	const char* ip;
+	struct mg_context* ctx;
+};
+
+// Forward declarations...
+static int endpointDiscoveryServer_callback(struct mg_connection *conn);
+static char* format_path(const char* path);
+
+#ifndef ANDROID
+static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip);
+#endif
+
+celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server) {
+	celix_status_t status;
+
+	const char *port = NULL;
+	const char *ip = NULL;
+	char *detectedIp = NULL;
+	const char *path = NULL;
+	const char *retries = NULL;
+
+	int max_ep_num = MAX_NUMBER_OF_RESTARTS;
+
+	*server = malloc(sizeof(struct endpoint_discovery_server));
+	if (!*server) {
+		return CELIX_ENOMEM;
+	}
+
+	(*server)->loghelper = &discovery->loghelper;
+	(*server)->entries = hashMap_create(&utils_stringHash, NULL, &utils_stringEquals, NULL);
+	if (!(*server)->entries) {
+		return CELIX_ENOMEM;
+	}
+
+	status = celixThreadMutex_create(&(*server)->serverLock, NULL);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	bundleContext_getProperty(context, DISCOVERY_SERVER_IP, &ip);
+#ifndef ANDROID
+	if (ip == NULL) {
+		const char *interface = NULL;
+
+		bundleContext_getProperty(context, DISCOVERY_SERVER_INTERFACE, &interface);
+		if ((interface != NULL) && (endpointDiscoveryServer_getIpAdress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
+			logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "Could not retrieve IP adress for interface %s", interface);
+		}
+
+		if (detectedIp == NULL) {
+			endpointDiscoveryServer_getIpAdress(NULL, &detectedIp);
+		}
+
+		ip = detectedIp;
+	}
+#endif
+
+	if (ip != NULL) {
+		logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_INFO, "Using %s for service annunciation", ip);
+		(*server)->ip = strdup(ip);
+	}
+	else {
+		logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "No IP address for service annunciation set. Using %s", DEFAULT_SERVER_IP);
+		(*server)->ip = strdup((char*) DEFAULT_SERVER_IP);
+	}
+
+	if (detectedIp != NULL) {
+		free(detectedIp);
+	}
+
+	bundleContext_getProperty(context, DISCOVERY_SERVER_PORT, &port);
+	if (port == NULL) {
+		port = DEFAULT_SERVER_PORT;
+	}
+
+	bundleContext_getProperty(context, DISCOVERY_SERVER_PATH, &path);
+	if (path == NULL) {
+		path = DEFAULT_SERVER_PATH;
+	}
+
+	bundleContext_getProperty(context, DISCOVERY_SERVER_MAX_EP, &retries);
+	if (retries != NULL) {
+		errno=0;
+		max_ep_num = strtol(retries,NULL,10);
+		if(errno!=0 || max_ep_num<=0){
+			max_ep_num=MAX_NUMBER_OF_RESTARTS;
+		}
+	}
+
+	(*server)->path = format_path(path);
+
+	const struct mg_callbacks callbacks = {
+			.begin_request = endpointDiscoveryServer_callback,
+	};
+
+	unsigned int port_counter = 0;
+	char newPort[10];
+
+	do {
+		const char *options[] = {
+				"listening_ports", port,
+				"num_threads", DEFAULT_SERVER_THREADS,
+				NULL
+		};
+
+		(*server)->ctx = mg_start(&callbacks, (*server), options);
+
+		if ((*server)->ctx != NULL)
+		{
+			logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Starting discovery server on port %s...", port);
+		}
+		else {
+			errno = 0;
+			char* endptr = (char*)port;
+			long currentPort = strtol(port, &endptr, 10);
+
+			if (*endptr || errno != 0) {
+				currentPort = strtol(DEFAULT_SERVER_PORT, NULL, 10);
+			}
+
+			port_counter++;
+			snprintf(&newPort[0], 10,  "%ld", (currentPort+1));
+
+			logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting discovery server on port %s - retrying on port %s...", port, newPort);
+			port = newPort;
+
+		}
+
+	} while(((*server)->ctx == NULL) && (port_counter < max_ep_num));
+
+	(*server)->port = strdup(port);
+
+	return status;
+}
+
+celix_status_t endpointDiscoveryServer_getUrl(endpoint_discovery_server_pt server, char* url)
+{
+	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+	if (server->ip && server->port && server->path) {
+		sprintf(url, "http://%s:%s/%s", server->ip, server->port, server->path);
+		status = CELIX_SUCCESS;
+	}
+
+	return status;
+}
+
+celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt server) {
+	celix_status_t status;
+
+	// stop & block until the actual server is shut down...
+	if (server->ctx != NULL) {
+		mg_stop(server->ctx);
+		server->ctx = NULL;
+	}
+
+	status = celixThreadMutex_lock(&server->serverLock);
+
+	hashMap_destroy(server->entries, true /* freeKeys */, false /* freeValues */);
+
+	status = celixThreadMutex_unlock(&server->serverLock);
+	status = celixThreadMutex_destroy(&server->serverLock);
+
+	free((void*) server->path);
+	free((void*) server->port);
+	free((void*) server->ip);
+
+	free(server);
+
+	return status;
+}
+
+celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&server->serverLock);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	// create a local copy of the endpointId which we can control...
+	char* endpointId = strdup(endpoint->id);
+	endpoint_description_pt cur_value = hashMap_get(server->entries, endpointId);
+	if (!cur_value) {
+		logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "exposing new endpoint \"%s\"...", endpointId);
+
+		hashMap_put(server->entries, endpointId, endpoint);
+	}
+
+	status = celixThreadMutex_unlock(&server->serverLock);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	return status;
+}
+
+celix_status_t endpointDiscoveryServer_removeEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&server->serverLock);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	hash_map_entry_pt entry = hashMap_getEntry(server->entries, endpoint->id);
+	if (entry) {
+		char* key = hashMapEntry_getKey(entry);
+
+		logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "removing endpoint \"%s\"...\n", key);
+
+		hashMap_remove(server->entries, key);
+
+		// we've made this key, see _addEnpoint above...
+		free((void*) key);
+	}
+
+	status = celixThreadMutex_unlock(&server->serverLock);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	return status;
+}
+
+static char* format_path(const char* path) {
+	char* result = strdup(path);
+	result = utils_stringTrim(result);
+	// check whether the path starts with a leading slash...
+	if (result[0] != '/') {
+		size_t len = strlen(result);
+		result = realloc(result, len + 2);
+		memmove(result + 1, result, len);
+		result[0] = '/';
+		result[len + 1] = 0;
+	}
+	return result;
+}
+
+static celix_status_t endpointDiscoveryServer_getEndpoints(endpoint_discovery_server_pt server, const char* the_endpoint_id, array_list_pt *endpoints) {
+	celix_status_t status;
+
+	status = arrayList_create(endpoints);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_ENOMEM;
+	}
+
+
+	hash_map_iterator_pt iter = hashMapIterator_create(server->entries);
+	while (hashMapIterator_hasNext(iter)) {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+		char* endpoint_id = hashMapEntry_getKey(entry);
+		if (the_endpoint_id == NULL || strcmp(the_endpoint_id, endpoint_id) == 0) {
+			endpoint_description_pt endpoint = hashMapEntry_getValue(entry);
+
+			arrayList_add(*endpoints, endpoint);
+		}
+	}
+	hashMapIterator_destroy(iter);
+
+	return status;
+}
+
+static int endpointDiscoveryServer_writeEndpoints(struct mg_connection* conn, array_list_pt endpoints) {
+	celix_status_t status;
+	int rv = CIVETWEB_REQUEST_NOT_HANDLED;
+
+	endpoint_descriptor_writer_pt writer = NULL;
+	status = endpointDescriptorWriter_create(&writer);
+	if (status == CELIX_SUCCESS) {
+
+		char *buffer = NULL;
+		status = endpointDescriptorWriter_writeDocument(writer, endpoints, &buffer);
+		if (buffer) {
+			mg_write(conn, response_headers, strlen(response_headers));
+			mg_write(conn, buffer, strlen(buffer));
+		}
+
+		rv = CIVETWEB_REQUEST_HANDLED;
+	}
+
+	if(writer!=NULL){
+		endpointDescriptorWriter_destroy(writer);
+	}
+
+	return rv;
+}
+
+// returns all endpoints as XML...
+static int endpointDiscoveryServer_returnAllEndpoints(endpoint_discovery_server_pt server, struct mg_connection* conn) {
+	int status = CIVETWEB_REQUEST_NOT_HANDLED;
+
+	array_list_pt endpoints = NULL;
+
+	if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) {
+		endpointDiscoveryServer_getEndpoints(server, NULL, &endpoints);
+		if (endpoints) {
+			status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
+
+			arrayList_destroy(endpoints);
+		}
+
+
+		celixThreadMutex_unlock(&server->serverLock);
+	}
+
+	return status;
+}
+
+// returns a single endpoint as XML...
+static int endpointDiscoveryServer_returnEndpoint(endpoint_discovery_server_pt server, struct mg_connection* conn, const char* endpoint_id) {
+	int status = CIVETWEB_REQUEST_NOT_HANDLED;
+
+	array_list_pt endpoints = NULL;
+
+	if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) {
+		endpointDiscoveryServer_getEndpoints(server, endpoint_id, &endpoints);
+		if (endpoints) {
+			status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
+
+			arrayList_destroy(endpoints);
+		}
+
+		celixThreadMutex_unlock(&server->serverLock);
+	}
+
+	return status;
+}
+
+static int endpointDiscoveryServer_callback(struct mg_connection* conn) {
+	int status = CIVETWEB_REQUEST_NOT_HANDLED;
+
+	const struct mg_request_info *request_info = mg_get_request_info(conn);
+	if (request_info->uri != NULL && strcmp("GET", request_info->request_method) == 0) {
+		endpoint_discovery_server_pt server = request_info->user_data;
+
+		const char *uri = request_info->uri;
+		const size_t path_len = strlen(server->path);
+		const size_t uri_len = strlen(uri);
+
+		if (strncmp(server->path, uri, strlen(server->path)) == 0) {
+			// Be lenient when it comes to the trailing slash...
+			if (path_len == uri_len || (uri_len == (path_len + 1) && uri[path_len] == '/')) {
+				status = endpointDiscoveryServer_returnAllEndpoints(server, conn);
+			} else {
+				const char* endpoint_id = uri + path_len + 1; // right after the slash...
+
+				status = endpointDiscoveryServer_returnEndpoint(server, conn, endpoint_id);
+			}
+		}
+	}
+
+	return status;
+}
+
+#ifndef ANDROID
+static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip) {
+	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+	struct ifaddrs *ifaddr, *ifa;
+	char host[NI_MAXHOST];
+
+	if (getifaddrs(&ifaddr) != -1)
+	{
+		for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+		{
+			if (ifa->ifa_addr == NULL)
+				continue;
+
+			if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+				if (interface == NULL) {
+					*ip = strdup(host);
+					status = CELIX_SUCCESS;
+				}
+				else if (strcmp(ifa->ifa_name, interface) == 0) {
+					*ip = strdup(host);
+					status = CELIX_SUCCESS;
+				}
+			}
+		}
+
+		freeifaddrs(ifaddr);
+	}
+
+	return status;
+}
+#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/md5.inl
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/md5.inl b/remote_services/discovery_common/src/md5.inl
new file mode 100644
index 0000000..4da933d
--- /dev/null
+++ b/remote_services/discovery_common/src/md5.inl
@@ -0,0 +1,461 @@
+/*
+ * This an amalgamation of md5.c and md5.h into a single file
+ * with all static declaration to reduce linker conflicts
+ * in Civetweb.
+ *
+ * The MD5_STATIC declaration was added to facilitate static
+ * inclusion.
+ * No Face Press, LLC
+ */
+
+/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.h is L. Peter Deutsch
+  <gh...@aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Removed support for non-ANSI compilers; removed
+	references to Ghostscript; clarified derivation from RFC 1321;
+	now handles byte order either statically or dynamically.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+	added conditionalization for C++ compilation from Martin
+	Purschke <pu...@bnl.gov>.
+  1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+#  define md5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+    md5_word_t count[2];	/* message length in bits, lsw first */
+    md5_word_t abcd[4];		/* digest buffer */
+    md5_byte_t buf[64];		/* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Initialize the algorithm. */
+MD5_STATIC void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+MD5_STATIC void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+MD5_STATIC void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+}  /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
+
+/*
+  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost@aladdin.com
+
+ */
+/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.c is L. Peter Deutsch
+  <gh...@aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+	either statically or dynamically; added missing #include <string.h>
+	in library.
+  2002-03-11 lpd Corrected argument list for main(), and added int return
+	type, in test program and T value program.
+  2002-02-21 lpd Added missing #include <stdio.h> in test program.
+  2000-07-03 lpd Patched to eliminate warnings about "constant is
+	unsigned in ANSI C, signed in traditional"; made test program
+	self-checking.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+  1999-05-03 lpd Original version.
+ */
+
+#ifndef MD5_STATIC
+#include <string.h>
+#endif
+
+#undef BYTE_ORDER	/* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#ifdef ARCH_IS_BIG_ENDIAN
+#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+#  define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3    0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6    0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9    0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13    0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16    0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19    0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22    0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25    0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28    0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31    0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35    0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38    0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41    0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44    0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47    0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50    0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53    0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57    0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60    0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63    0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+    md5_word_t
+    a = pms->abcd[0], b = pms->abcd[1],
+    c = pms->abcd[2], d = pms->abcd[3];
+    md5_word_t t;
+#if BYTE_ORDER > 0
+    /* Define storage only for big-endian CPUs. */
+    md5_word_t X[16];
+#else
+    /* Define storage for little-endian or both types of CPUs. */
+    md5_word_t xbuf[16];
+    const md5_word_t *X;
+#endif
+
+    {
+#if BYTE_ORDER == 0
+        /*
+         * Determine dynamically whether this is a big-endian or
+         * little-endian machine, since we can use a more efficient
+         * algorithm on the latter.
+         */
+        static const int w = 1;
+
+        if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0		/* little-endian */
+        {
+            /*
+             * On little-endian machines, we can process properly aligned
+             * data without copying it.
+             */
+            if (!((data - (const md5_byte_t *)0) & 3)) {
+                /* data are properly aligned */
+                X = (const md5_word_t *)data;
+            } else {
+                /* not aligned */
+                memcpy(xbuf, data, 64);
+                X = xbuf;
+            }
+        }
+#endif
+#if BYTE_ORDER == 0
+        else			/* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0		/* big-endian */
+        {
+            /*
+             * On big-endian machines, we must arrange the bytes in the
+             * right order.
+             */
+            const md5_byte_t *xp = data;
+            int i;
+
+#  if BYTE_ORDER == 0
+            X = xbuf;		/* (dynamic only) */
+#  else
+#    define xbuf X		/* (static only) */
+#  endif
+            for (i = 0; i < 16; ++i, xp += 4)
+                xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+        }
+#endif
+    }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+    /* Round 1. */
+    /* Let [abcd k s i] denote the operation
+       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + F(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+    /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  7,  T1);
+    SET(d, a, b, c,  1, 12,  T2);
+    SET(c, d, a, b,  2, 17,  T3);
+    SET(b, c, d, a,  3, 22,  T4);
+    SET(a, b, c, d,  4,  7,  T5);
+    SET(d, a, b, c,  5, 12,  T6);
+    SET(c, d, a, b,  6, 17,  T7);
+    SET(b, c, d, a,  7, 22,  T8);
+    SET(a, b, c, d,  8,  7,  T9);
+    SET(d, a, b, c,  9, 12, T10);
+    SET(c, d, a, b, 10, 17, T11);
+    SET(b, c, d, a, 11, 22, T12);
+    SET(a, b, c, d, 12,  7, T13);
+    SET(d, a, b, c, 13, 12, T14);
+    SET(c, d, a, b, 14, 17, T15);
+    SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+    /* Round 2. */
+    /* Let [abcd k s i] denote the operation
+         a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + G(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+    /* Do the following 16 operations. */
+    SET(a, b, c, d,  1,  5, T17);
+    SET(d, a, b, c,  6,  9, T18);
+    SET(c, d, a, b, 11, 14, T19);
+    SET(b, c, d, a,  0, 20, T20);
+    SET(a, b, c, d,  5,  5, T21);
+    SET(d, a, b, c, 10,  9, T22);
+    SET(c, d, a, b, 15, 14, T23);
+    SET(b, c, d, a,  4, 20, T24);
+    SET(a, b, c, d,  9,  5, T25);
+    SET(d, a, b, c, 14,  9, T26);
+    SET(c, d, a, b,  3, 14, T27);
+    SET(b, c, d, a,  8, 20, T28);
+    SET(a, b, c, d, 13,  5, T29);
+    SET(d, a, b, c,  2,  9, T30);
+    SET(c, d, a, b,  7, 14, T31);
+    SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+    /* Round 3. */
+    /* Let [abcd k s t] denote the operation
+         a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + H(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+    /* Do the following 16 operations. */
+    SET(a, b, c, d,  5,  4, T33);
+    SET(d, a, b, c,  8, 11, T34);
+    SET(c, d, a, b, 11, 16, T35);
+    SET(b, c, d, a, 14, 23, T36);
+    SET(a, b, c, d,  1,  4, T37);
+    SET(d, a, b, c,  4, 11, T38);
+    SET(c, d, a, b,  7, 16, T39);
+    SET(b, c, d, a, 10, 23, T40);
+    SET(a, b, c, d, 13,  4, T41);
+    SET(d, a, b, c,  0, 11, T42);
+    SET(c, d, a, b,  3, 16, T43);
+    SET(b, c, d, a,  6, 23, T44);
+    SET(a, b, c, d,  9,  4, T45);
+    SET(d, a, b, c, 12, 11, T46);
+    SET(c, d, a, b, 15, 16, T47);
+    SET(b, c, d, a,  2, 23, T48);
+#undef SET
+
+    /* Round 4. */
+    /* Let [abcd k s t] denote the operation
+         a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + I(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+    /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  6, T49);
+    SET(d, a, b, c,  7, 10, T50);
+    SET(c, d, a, b, 14, 15, T51);
+    SET(b, c, d, a,  5, 21, T52);
+    SET(a, b, c, d, 12,  6, T53);
+    SET(d, a, b, c,  3, 10, T54);
+    SET(c, d, a, b, 10, 15, T55);
+    SET(b, c, d, a,  1, 21, T56);
+    SET(a, b, c, d,  8,  6, T57);
+    SET(d, a, b, c, 15, 10, T58);
+    SET(c, d, a, b,  6, 15, T59);
+    SET(b, c, d, a, 13, 21, T60);
+    SET(a, b, c, d,  4,  6, T61);
+    SET(d, a, b, c, 11, 10, T62);
+    SET(c, d, a, b,  2, 15, T63);
+    SET(b, c, d, a,  9, 21, T64);
+#undef SET
+
+    /* Then perform the following additions. (That is increment each
+       of the four registers by the value it had before this block
+       was started.) */
+    pms->abcd[0] += a;
+    pms->abcd[1] += b;
+    pms->abcd[2] += c;
+    pms->abcd[3] += d;
+}
+
+MD5_STATIC void
+md5_init(md5_state_t *pms)
+{
+    pms->count[0] = pms->count[1] = 0;
+    pms->abcd[0] = 0x67452301;
+    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+    pms->abcd[3] = 0x10325476;
+}
+
+MD5_STATIC void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+    const md5_byte_t *p = data;
+    int left = nbytes;
+    int offset = (pms->count[0] >> 3) & 63;
+    md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+    if (nbytes <= 0)
+        return;
+
+    /* Update the message length. */
+    pms->count[1] += nbytes >> 29;
+    pms->count[0] += nbits;
+    if (pms->count[0] < nbits)
+        pms->count[1]++;
+
+    /* Process an initial partial block. */
+    if (offset) {
+        int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+        memcpy(pms->buf + offset, p, copy);
+        if (offset + copy < 64)
+            return;
+        p += copy;
+        left -= copy;
+        md5_process(pms, pms->buf);
+    }
+
+    /* Process full blocks. */
+    for (; left >= 64; p += 64, left -= 64)
+        md5_process(pms, p);
+
+    /* Process a final partial block. */
+    if (left)
+        memcpy(pms->buf, p, left);
+}
+
+MD5_STATIC void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+    static const md5_byte_t pad[64] = {
+        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    };
+    md5_byte_t data[8];
+    int i;
+
+    /* Save the length before padding. */
+    for (i = 0; i < 8; ++i)
+        data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+    /* Pad to 56 bytes mod 64. */
+    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+    /* Append the length. */
+    md5_append(pms, data, 8);
+    for (i = 0; i < 16; ++i)
+        digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/CMakeLists.txt b/remote_services/discovery_configured/CMakeLists.txt
index b9f849d..e0f3e9b 100644
--- a/remote_services/discovery_configured/CMakeLists.txt
+++ b/remote_services/discovery_configured/CMakeLists.txt
@@ -19,39 +19,19 @@ if (RSA_DISCOVERY_CONFIGURED)
     find_package(CURL REQUIRED)
     find_package(LibXml2 REQUIRED)
 
-    include_directories("${CURL_INCLUDE_DIR}")
-    include_directories("${LIBXML2_INCLUDE_DIR}")
-    include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery/private/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery_configured/private/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
-    include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
-    include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-    include_directories(private/include)
-
     add_bundle(discovery_configured 
-    VERSION 0.9.0
-    SYMBOLIC_NAME "apache_celix_rsa_discovery_configured"
-    NAME "Apache Celix RSA Configured Discovery"    
-    SOURCES
-
-	private/src/discovery_impl.c
-	${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery_activator.c
-	${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery.c
-	${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_reader.c
-	${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_writer.c
-	${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_poller.c
-	${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_server.c
-	${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
-	${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
+        VERSION 0.9.0
+        SYMBOLIC_NAME "apache_celix_rsa_discovery_configured"
+        NAME "Apache Celix RSA Configured Discovery"
+        SOURCES
+	        src/discovery_impl.c
     )
-    target_link_libraries(discovery_configured PRIVATE Celix::log_helper)
+    target_include_directories(discovery_configured PRIVATE src)
+    target_link_libraries(discovery_configured PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} Celix::log_helper discovery_common)
 
     install_bundle(discovery_configured)
 
-    target_link_libraries(discovery_configured PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES})
+
 
     if (RSA_ENDPOINT_TEST_READER)
         add_executable(descparser


[12/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/civetweb.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/civetweb.c b/remote_services/discovery_common/src/civetweb.c
new file mode 100644
index 0000000..a6093b7
--- /dev/null
+++ b/remote_services/discovery_common/src/civetweb.c
@@ -0,0 +1,7907 @@
+	/* Copyright (c) 2013-2015 the Civetweb developers
+ * Copyright (c) 2004-2013 Sergey Lyubka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if defined(_WIN32)
+#if !defined(_CRT_SECURE_NO_WARNINGS)
+#define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */
+#endif
+#else
+#ifdef __linux__
+#define _XOPEN_SOURCE 600     /* For flockfile() on Linux */
+#endif
+#ifndef _LARGEFILE_SOURCE
+#define _LARGEFILE_SOURCE     /* For fseeko(), ftello() */
+#endif
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64  /* Use 64-bit file offsets by default */
+#endif
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS  /* <inttypes.h> wants this for C++ */
+#endif
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS   /* C++ wants that for INT64_MAX */
+#endif
+#endif
+
+#if defined (_MSC_VER)
+/* 'type cast' : conversion from 'int' to 'HANDLE' of greater size */
+#pragma warning (disable : 4306 )
+/* conditional expression is constant: introduced by FD_SET(..) */
+#pragma warning (disable : 4127)
+/* non-constant aggregate initializer: issued due to missing C99 support */
+#pragma warning (disable : 4204)
+#endif
+
+/* Disable WIN32_LEAN_AND_MEAN.
+   This makes windows.h always include winsock2.h */
+#if defined(WIN32_LEAN_AND_MEAN)
+#undef WIN32_LEAN_AND_MEAN
+#endif
+
+#if defined USE_IPV6 && defined(_WIN32)
+#include <ws2tcpip.h>
+#endif
+
+#if defined(__SYMBIAN32__)
+#define NO_SSL /* SSL is not supported */
+#define NO_CGI /* CGI is not supported */
+#define PATH_MAX FILENAME_MAX
+#endif /* __SYMBIAN32__ */
+
+#ifndef IGNORE_UNUSED_RESULT
+#define IGNORE_UNUSED_RESULT(a) (void)((a) && 1)
+#endif
+
+#ifndef _WIN32_WCE /* Some ANSI #includes are not available on Windows CE */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#endif /* !_WIN32_WCE */
+
+#include <time.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#ifndef MAX_WORKER_THREADS
+#define MAX_WORKER_THREADS (1024*64)
+#endif
+
+#if defined(_WIN32) && !defined(__SYMBIAN32__) /* Windows specific */
+#if defined(_MSC_VER) && _MSC_VER <= 1400
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400 /* To make it link in VS2005 */
+#endif
+#include <windows.h>
+typedef const char * SOCK_OPT_TYPE;
+
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+
+#ifndef _IN_PORT_T
+#ifndef in_port_t
+#define in_port_t u_short
+#endif
+#endif
+
+#ifndef _WIN32_WCE
+#include <process.h>
+#include <direct.h>
+#include <io.h>
+#else /* _WIN32_WCE */
+#define NO_CGI /* WinCE has no pipes */
+
+typedef long off_t;
+
+#define errno   GetLastError()
+#define strerror(x)  _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10)
+#endif /* _WIN32_WCE */
+
+#define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \
+      ((uint64_t)((uint32_t)(hi))) << 32))
+#define RATE_DIFF 10000000 /* 100 nsecs */
+#define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de)
+#define SYS2UNIX_TIME(lo, hi) \
+  (time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)
+
+/* Visual Studio 6 does not know __func__ or __FUNCTION__
+   The rest of MS compilers use __FUNCTION__, not C99 __func__
+   Also use _strtoui64 on modern M$ compilers */
+#if defined(_MSC_VER) && _MSC_VER < 1300
+#define STRX(x) #x
+#define STR(x) STRX(x)
+#define __func__ __FILE__ ":" STR(__LINE__)
+#define strtoull(x, y, z) (unsigned __int64) _atoi64(x)
+#define strtoll(x, y, z) _atoi64(x)
+#else
+#define __func__  __FUNCTION__
+#define strtoull(x, y, z) _strtoui64(x, y, z)
+#define strtoll(x, y, z) _strtoi64(x, y, z)
+#endif /* _MSC_VER */
+
+#define ERRNO   GetLastError()
+#define NO_SOCKLEN_T
+#define SSL_LIB   "ssleay32.dll"
+#define CRYPTO_LIB  "libeay32.dll"
+#define O_NONBLOCK  0
+#define W_OK (2) /* http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx */
+#if !defined(EWOULDBLOCK)
+#define EWOULDBLOCK  WSAEWOULDBLOCK
+#endif /* !EWOULDBLOCK */
+#define _POSIX_
+#define INT64_FMT  "I64d"
+
+#define WINCDECL __cdecl
+#define SHUT_WR 1
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define access _access
+#define mg_sleep(x) Sleep(x)
+
+#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
+#ifndef popen
+#define popen(x, y) _popen(x, y)
+#endif
+#ifndef pclose
+#define pclose(x) _pclose(x)
+#endif
+#define close(x) _close(x)
+#define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y))
+#define RTLD_LAZY  0
+#define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z))
+#define fdopen(x, y) _fdopen((x), (y))
+#define write(x, y, z) _write((x), (y), (unsigned) z)
+#define read(x, y, z) _read((x), (y), (unsigned) z)
+#define flockfile(x) EnterCriticalSection(&global_log_file_lock)
+#define funlockfile(x) LeaveCriticalSection(&global_log_file_lock)
+#define sleep(x) Sleep((x) * 1000)
+#define rmdir(x) _rmdir(x)
+
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+#define USE_TIMERS
+#endif
+
+#if !defined(va_copy)
+#define va_copy(x, y) x = y
+#endif /* !va_copy MINGW #defines va_copy */
+
+#if !defined(fileno)
+#define fileno(x) _fileno(x)
+#endif /* !fileno MINGW #defines fileno */
+
+typedef HANDLE pthread_mutex_t;
+typedef DWORD pthread_key_t;
+typedef HANDLE pthread_t;
+typedef struct {
+    CRITICAL_SECTION threadIdSec;
+    int waitingthreadcount;        /* The number of threads queued. */
+    pthread_t *waitingthreadhdls;  /* The thread handles. */
+} pthread_cond_t;
+
+#ifndef __clockid_t_defined
+typedef DWORD clockid_t;
+#endif
+#ifndef CLOCK_MONOTONIC
+#define CLOCK_MONOTONIC (1)
+#endif
+#ifndef CLOCK_REALTIME
+#define CLOCK_REALTIME  (2)
+#endif
+
+#ifndef _TIMESPEC_DEFINED
+struct timespec {
+    time_t   tv_sec;        /* seconds */
+    long     tv_nsec;       /* nanoseconds */
+};
+#endif
+
+#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */
+
+static int pthread_mutex_lock(pthread_mutex_t *);
+static int pthread_mutex_unlock(pthread_mutex_t *);
+static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
+struct file;
+static char *mg_fgets(char *buf, size_t size, struct file *filep, char **p);
+
+#if defined(HAVE_STDINT)
+#include <stdint.h>
+#else
+typedef unsigned int  uint32_t;
+typedef unsigned short  uint16_t;
+typedef unsigned __int64 uint64_t;
+typedef __int64   int64_t;
+#define INT64_MAX  9223372036854775807
+#endif /* HAVE_STDINT */
+
+/* POSIX dirent interface */
+struct dirent {
+    char d_name[PATH_MAX];
+};
+
+typedef struct DIR {
+    HANDLE   handle;
+    WIN32_FIND_DATAW info;
+    struct dirent  result;
+} DIR;
+
+#if !defined(USE_IPV6) && defined(_WIN32)
+#ifndef HAVE_POLL
+struct pollfd {
+    SOCKET fd;
+    short events;
+    short revents;
+};
+#define POLLIN 1
+#endif
+#endif
+
+/* Mark required libraries */
+#ifdef _MSC_VER
+#pragma comment(lib, "Ws2_32.lib")
+#endif
+
+#else    /* UNIX  specific */
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <sys/utsname.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <netdb.h>
+typedef const void * SOCK_OPT_TYPE;
+
+//#if defined(ANDROID)
+typedef unsigned short int in_port_t;
+//#endif
+
+#include <pwd.h>
+#include <unistd.h>
+#include <dirent.h>
+#if !defined(NO_SSL_DL) && !defined(NO_SSL)
+#include <dlfcn.h>
+#endif
+#include <pthread.h>
+#if defined(__MACH__)
+#define SSL_LIB   "libssl.dylib"
+#define CRYPTO_LIB  "libcrypto.dylib"
+#else
+#if !defined(SSL_LIB)
+#define SSL_LIB   "libssl.so"
+#endif
+#if !defined(CRYPTO_LIB)
+#define CRYPTO_LIB  "libcrypto.so"
+#endif
+#endif
+#ifndef O_BINARY
+#define O_BINARY  0
+#endif /* O_BINARY */
+#define closesocket(a) close(a)
+#define mg_mkdir(x, y) mkdir(x, y)
+#define mg_remove(x) remove(x)
+#define mg_sleep(x) usleep((x) * 1000)
+#define ERRNO errno
+#define INVALID_SOCKET (-1)
+#define INT64_FMT PRId64
+typedef int SOCKET;
+#define WINCDECL
+
+#endif /* End of Windows and UNIX specific includes */
+
+#ifdef _WIN32
+static CRITICAL_SECTION global_log_file_lock;
+static DWORD pthread_self(void)
+{
+    return GetCurrentThreadId();
+}
+
+int pthread_key_create(pthread_key_t *key, void (*_must_be_zero)(void*) /* destructor function not supported for windows */)
+{
+    assert(_must_be_zero == NULL);
+    if ((key!=0) && (_must_be_zero == NULL)) {
+        *key = TlsAlloc();
+        return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1;
+    }
+    return -2;
+}
+
+int pthread_key_delete(pthread_key_t key)
+{
+    return TlsFree(key) ? 0 : 1;
+}
+
+int pthread_setspecific(pthread_key_t key, void * value)
+{
+    return TlsSetValue(key, value) ? 0 : 1;
+}
+
+void *pthread_getspecific(pthread_key_t key)
+{
+    return TlsGetValue(key);
+}
+#endif /* _WIN32 */
+
+
+#include "civetweb.h"
+
+#define PASSWORDS_FILE_NAME ".htpasswd"
+#define CGI_ENVIRONMENT_SIZE 4096
+#define MAX_CGI_ENVIR_VARS 64
+#define MG_BUF_LEN 8192
+#ifndef MAX_REQUEST_SIZE
+#define MAX_REQUEST_SIZE 16384
+#endif
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+
+#if !defined(DEBUG_TRACE)
+#if defined(CWDEBUG)
+
+static void DEBUG_TRACE_FUNC(const char *func, unsigned line, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(3, 4);
+
+static void DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...) {
+
+  va_list args;
+  flockfile(stdout);
+ printf("*** %lu.%p.%s.%u: ",
+         (unsigned long) time(NULL), (void *) pthread_self(),
+         func, line);
+  va_start(args, fmt);
+  vprintf(fmt, args);
+  va_end(args);
+  putchar('\n');
+  fflush(stdout);
+  funlockfile(stdout);
+}
+
+#define DEBUG_TRACE(fmt, ...) DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
+
+#else
+#define DEBUG_TRACE(fmt, ...)
+#endif /* CWDEBUG */
+#endif /* DEBUG_TRACE */
+
+#if defined(MEMORY_DEBUGGING)
+static unsigned long blockCount = 0;
+static unsigned long totalMemUsed = 0;
+
+static void * mg_malloc_ex(size_t size, const char * file, unsigned line) {
+
+    void * data = malloc(size + sizeof(size_t));
+    void * memory = 0;
+    char mallocStr[256];
+
+    if (data) {
+        *(size_t*)data = size;
+        totalMemUsed += size;
+        blockCount++;
+        memory = (void *)(((char*)data)+sizeof(size_t));
+    }
+
+    sprintf(mallocStr, "MEM: %p %5lu alloc   %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+    OutputDebugStringA(mallocStr);
+#else
+    DEBUG_TRACE("%s", mallocStr);
+#endif
+
+    return memory;
+}
+
+static void * mg_calloc_ex(size_t count, size_t size, const char * file, unsigned line) {
+
+    void * data = mg_malloc_ex(size*count, file, line);
+    if (data) memset(data, 0, size);
+
+    return data;
+}
+
+static void mg_free_ex(void * memory, const char * file, unsigned line) {
+
+    char mallocStr[256];
+    void * data = (void *)(((char*)memory)-sizeof(size_t));
+    size_t size;
+
+    if (memory) {
+        size = *(size_t*)data;
+        totalMemUsed -= size;
+        blockCount--;
+        sprintf(mallocStr, "MEM: %p %5lu free    %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+        OutputDebugStringA(mallocStr);
+#else
+        DEBUG_TRACE("%s", mallocStr);
+#endif
+
+        free(data);
+    }
+}
+
+static void * mg_realloc_ex(void * memory, size_t newsize, const char * file, unsigned line) {
+
+    char mallocStr[256];
+    void * data;
+    void * _realloc;
+    size_t oldsize;
+
+    if (newsize) {
+        if (memory) {
+            data = (void *)(((char*)memory)-sizeof(size_t));
+            oldsize = *(size_t*)data;
+            _realloc = realloc(data, newsize+sizeof(size_t));
+            if (_realloc) {
+                data = _realloc;
+                totalMemUsed -= oldsize;
+                sprintf(mallocStr, "MEM: %p %5lu r-free  %7lu %4lu --- %s:%u\n", memory, (unsigned long)oldsize, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+                OutputDebugStringA(mallocStr);
+#else
+                DEBUG_TRACE("%s", mallocStr);
+#endif
+                totalMemUsed += newsize;
+                sprintf(mallocStr, "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)newsize, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+                OutputDebugStringA(mallocStr);
+#else
+                DEBUG_TRACE("%s", mallocStr);
+#endif
+                *(size_t*)data = newsize;
+                data = (void *)(((char*)data)+sizeof(size_t));
+            } else {
+#if defined(_WIN32)
+                OutputDebugStringA("MEM: realloc failed\n");
+#else
+                DEBUG_TRACE("%s", "MEM: realloc failed\n");
+#endif
+                return _realloc;
+            }
+        } else {
+            data = mg_malloc_ex(newsize, file, line);
+        }
+    } else {
+        data = 0;
+        mg_free_ex(memory, file, line);
+    }
+
+    return data;
+}
+
+#define mg_malloc(a)      mg_malloc_ex(a, __FILE__, __LINE__)
+#define mg_calloc(a,b)    mg_calloc_ex(a, b, __FILE__, __LINE__)
+#define mg_realloc(a, b)  mg_realloc_ex(a, b, __FILE__, __LINE__)
+#define mg_free(a)        mg_free_ex(a, __FILE__, __LINE__)
+
+#else
+static __inline void * mg_malloc(size_t a)             {return malloc(a);}
+static __inline void * mg_calloc(size_t a, size_t b)   {return calloc(a, b);}
+static __inline void * mg_realloc(void * a, size_t b)  {return realloc(a, b);}
+static __inline void   mg_free(void * a)               {free(a);}
+#endif
+
+/* This following lines are just meant as a reminder to use the mg-functions for memory management */
+#ifdef malloc
+    #undef malloc
+#endif
+#ifdef calloc
+    #undef calloc
+#endif
+#ifdef realloc
+    #undef realloc
+#endif
+#ifdef free
+    #undef free
+#endif
+#define malloc  DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc
+#define calloc  DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc
+#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc
+#define free    DO_NOT_USE_THIS_FUNCTION__USE_mg_free
+
+
+#define MD5_STATIC static
+#include "md5.inl"
+
+/* Darwin prior to 7.0 and Win32 do not have socklen_t */
+#ifdef NO_SOCKLEN_T
+typedef int socklen_t;
+#endif /* NO_SOCKLEN_T */
+#define _DARWIN_UNLIMITED_SELECT
+
+#define IP_ADDR_STR_LEN 50  /* IPv6 hex string is 46 chars */
+
+#if !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+#if !defined(SOMAXCONN)
+#define SOMAXCONN 100
+#endif
+
+#if !defined(PATH_MAX)
+#define PATH_MAX 4096
+#endif
+
+/* Size of the accepted socket queue */
+#if !defined(MGSQLEN)
+#define MGSQLEN 20
+#endif
+
+#if defined(NO_SSL_DL)
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#else
+/* SSL loaded dynamically from DLL.
+   I put the prototypes here to be independent from OpenSSL source
+   installation. */
+
+typedef struct ssl_st SSL;
+typedef struct ssl_method_st SSL_METHOD;
+typedef struct ssl_ctx_st SSL_CTX;
+
+struct ssl_func {
+    const char *name;   /* SSL function name */
+    void  (*ptr)(void); /* Function pointer */
+};
+
+#define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr)
+#define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr)
+#define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr)
+#define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr)
+#define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr)
+#define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr)
+#define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr)
+#define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
+#define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
+#define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
+#define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr)
+#define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \
+        const char *, int)) ssl_sw[11].ptr)
+#define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \
+        const char *, int)) ssl_sw[12].ptr)
+#define SSL_CTX_set_default_passwd_cb \
+  (* (void (*)(SSL_CTX *, mg_callback_t)) ssl_sw[13].ptr)
+#define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr)
+#define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr)
+#define SSL_CTX_use_certificate_chain_file \
+  (* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr)
+#define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
+#define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr)
+#define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr)
+#define SSL_shutdown (* (int (*)(SSL *)) ssl_sw[20].ptr)
+
+#define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr)
+#define CRYPTO_set_locking_callback \
+  (* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr)
+#define CRYPTO_set_id_callback \
+  (* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr)
+#define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr)
+#define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr)
+
+/* set_ssl_option() function updates this array.
+   It loads SSL library dynamically and changes NULLs to the actual addresses
+   of respective functions. The macros above (like SSL_connect()) are really
+   just calling these functions indirectly via the pointer. */
+static struct ssl_func ssl_sw[] = {
+    {"SSL_free",   NULL},
+    {"SSL_accept",   NULL},
+    {"SSL_connect",   NULL},
+    {"SSL_read",   NULL},
+    {"SSL_write",   NULL},
+    {"SSL_get_error",  NULL},
+    {"SSL_set_fd",   NULL},
+    {"SSL_new",   NULL},
+    {"SSL_CTX_new",   NULL},
+    {"SSLv23_server_method", NULL},
+    {"SSL_library_init",  NULL},
+    {"SSL_CTX_use_PrivateKey_file", NULL},
+    {"SSL_CTX_use_certificate_file",NULL},
+    {"SSL_CTX_set_default_passwd_cb",NULL},
+    {"SSL_CTX_free",  NULL},
+    {"SSL_load_error_strings", NULL},
+    {"SSL_CTX_use_certificate_chain_file", NULL},
+    {"SSLv23_client_method", NULL},
+    {"SSL_pending", NULL},
+    {"SSL_CTX_set_verify", NULL},
+    {"SSL_shutdown",   NULL},
+    {NULL,    NULL}
+};
+
+/* Similar array as ssl_sw. These functions could be located in different
+   lib. */
+#if !defined(NO_SSL)
+static struct ssl_func crypto_sw[] = {
+    {"CRYPTO_num_locks",  NULL},
+    {"CRYPTO_set_locking_callback", NULL},
+    {"CRYPTO_set_id_callback", NULL},
+    {"ERR_get_error",  NULL},
+    {"ERR_error_string", NULL},
+    {NULL,    NULL}
+};
+#endif /* NO_SSL */
+#endif /* NO_SSL_DL */
+
+static const char *month_names[] = {
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+/* Unified socket address. For IPv6 support, add IPv6 address structure
+   in the union u. */
+union usa {
+    struct sockaddr sa;
+    struct sockaddr_in sin;
+#if defined(USE_IPV6)
+    struct sockaddr_in6 sin6;
+#endif
+};
+
+/* Describes a string (chunk of memory). */
+struct vec {
+    const char *ptr;
+    size_t len;
+};
+
+struct file {
+    int is_directory;
+    time_t modification_time;
+    int64_t size;
+    FILE *fp;
+    const char *membuf;   /* Non-NULL if file data is in memory */
+    /* set to 1 if the content is gzipped
+       in which case we need a content-encoding: gzip header */
+    int gzipped;
+};
+#define STRUCT_FILE_INITIALIZER {0, 0, 0, NULL, NULL, 0}
+
+/* Describes listening socket, or socket which was accept()-ed by the master
+   thread and queued for future handling by the worker thread. */
+struct socket {
+    SOCKET sock;          /* Listening socket */
+    union usa lsa;        /* Local socket address */
+    union usa rsa;        /* Remote socket address */
+    unsigned is_ssl:1;    /* Is port SSL-ed */
+    unsigned ssl_redir:1; /* Is port supposed to redirect everything to SSL
+                             port */
+};
+
+/* NOTE(lsm): this enum shoulds be in sync with the config_options below. */
+enum {
+    CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
+    PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS, THROTTLE,
+    ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
+    GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
+    EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
+    NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT,
+    DECODE_URL,
+
+#if defined(USE_LUA)
+    LUA_PRELOAD_FILE, LUA_SCRIPT_EXTENSIONS, LUA_SERVER_PAGE_EXTENSIONS,
+#endif
+#if defined(USE_WEBSOCKET)
+    WEBSOCKET_ROOT,
+#endif
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+    LUA_WEBSOCKET_EXTENSIONS,
+#endif
+    ACCESS_CONTROL_ALLOW_ORIGIN, ERROR_PAGES,
+
+    NUM_OPTIONS
+};
+
+/* Config option name, config types, default value */
+static struct mg_option config_options[] = {
+    {"cgi_pattern",                 CONFIG_TYPE_EXT_PATTERN,   "**.cgi$|**.pl$|**.php$"},
+    {"cgi_environment",             CONFIG_TYPE_STRING,        NULL},
+    {"put_delete_auth_file",        CONFIG_TYPE_FILE,          NULL},
+    {"cgi_interpreter",             CONFIG_TYPE_FILE,          NULL},
+    {"protect_uri",                 CONFIG_TYPE_STRING,        NULL},
+    {"authentication_domain",       CONFIG_TYPE_STRING,        "mydomain.com"},
+    {"ssi_pattern",                 CONFIG_TYPE_EXT_PATTERN,   "**.shtml$|**.shtm$"},
+    {"throttle",                    CONFIG_TYPE_STRING,        NULL},
+    {"access_log_file",             CONFIG_TYPE_FILE,          NULL},
+    {"enable_directory_listing",    CONFIG_TYPE_BOOLEAN,       "yes"},
+    {"error_log_file",              CONFIG_TYPE_FILE,          NULL},
+    {"global_auth_file",            CONFIG_TYPE_FILE,          NULL},
+    {"index_files",                 CONFIG_TYPE_STRING,
+#ifdef USE_LUA
+    "index.xhtml,index.html,index.htm,index.lp,index.lsp,index.lua,index.cgi,index.shtml,index.php"},
+#else
+    "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
+#endif
+    {"enable_keep_alive",           CONFIG_TYPE_BOOLEAN,       "no"},
+    {"access_control_list",         CONFIG_TYPE_STRING,        NULL},
+    {"extra_mime_types",            CONFIG_TYPE_STRING,        NULL},
+    {"listening_ports",             CONFIG_TYPE_STRING,        "8080"},
+    {"document_root",               CONFIG_TYPE_DIRECTORY,     NULL},
+    {"ssl_certificate",             CONFIG_TYPE_FILE,          NULL},
+    {"num_threads",                 CONFIG_TYPE_NUMBER,        "50"},
+    {"run_as_user",                 CONFIG_TYPE_STRING,        NULL},
+    {"url_rewrite_patterns",        CONFIG_TYPE_STRING,        NULL},
+    {"hide_files_patterns",         CONFIG_TYPE_EXT_PATTERN,   NULL},
+    {"request_timeout_ms",          CONFIG_TYPE_NUMBER,        "30000"},
+    {"decode_url",                  CONFIG_TYPE_BOOLEAN,       "yes"},
+
+#if defined(USE_LUA)
+    {"lua_preload_file",            CONFIG_TYPE_FILE,          NULL},
+    {"lua_script_pattern",          CONFIG_TYPE_EXT_PATTERN,   "**.lua$"},
+    {"lua_server_page_pattern",     CONFIG_TYPE_EXT_PATTERN,   "**.lp$|**.lsp$"},
+#endif
+#if defined(USE_WEBSOCKET)
+    {"websocket_root",              CONFIG_TYPE_DIRECTORY,     NULL},
+#endif
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+    {"lua_websocket_pattern",       CONFIG_TYPE_EXT_PATTERN,   "**.lua$"},
+#endif
+    {"access_control_allow_origin", CONFIG_TYPE_STRING,        "*"},
+    {"error_pages",                 CONFIG_TYPE_DIRECTORY,     NULL},
+
+    {NULL, CONFIG_TYPE_UNKNOWN, NULL}
+};
+
+struct mg_request_handler_info {
+    char *uri;
+    size_t uri_len;
+    mg_request_handler handler;
+
+    void *cbdata;
+    struct mg_request_handler_info *next;
+};
+
+struct mg_context {
+    volatile int stop_flag;         /* Should we stop event loop */
+    SSL_CTX *ssl_ctx;               /* SSL context */
+    char *config[NUM_OPTIONS];      /* Civetweb configuration parameters */
+    struct mg_callbacks callbacks;  /* User-defined callback function */
+    void *user_data;                /* User-defined data */
+    int context_type;               /* 1 = server context, 2 = client context */
+
+    struct socket *listening_sockets;
+    in_port_t *listening_ports;
+    int num_listening_sockets;
+
+    volatile int num_threads;       /* Number of threads */
+    pthread_mutex_t thread_mutex;   /* Protects (max|num)_threads */
+    pthread_cond_t thread_cond;     /* Condvar for tracking workers terminations */
+
+    struct socket queue[MGSQLEN];   /* Accepted sockets */
+    volatile int sq_head;           /* Head of the socket queue */
+    volatile int sq_tail;           /* Tail of the socket queue */
+    pthread_cond_t sq_full;         /* Signaled when socket is produced */
+    pthread_cond_t sq_empty;        /* Signaled when socket is consumed */
+    pthread_t masterthreadid;       /* The master thread ID */
+    int workerthreadcount;          /* The amount of worker threads. */
+    pthread_t *workerthreadids;     /* The worker thread IDs */
+
+    unsigned long start_time;       /* Server start time, used for authentication */
+    pthread_mutex_t nonce_mutex;    /* Protects nonce_count */
+    unsigned long nonce_count;      /* Used nonces, used for authentication */
+
+    char *systemName;               /* What operating system is running */
+
+    /* linked list of uri handlers */
+    struct mg_request_handler_info *request_handlers;
+
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+    /* linked list of shared lua websockets */
+    struct mg_shared_lua_websocket_list *shared_lua_websockets;
+#endif
+
+#ifdef USE_TIMERS
+    struct ttimers * timers;
+#endif
+};
+
+struct mg_connection {
+    struct mg_request_info request_info;
+    struct mg_context *ctx;
+    SSL *ssl;                       /* SSL descriptor */
+    SSL_CTX *client_ssl_ctx;        /* SSL context for client connections */
+    struct socket client;           /* Connected client */
+    time_t birth_time;              /* Time when request was received */
+    int64_t num_bytes_sent;         /* Total bytes sent to client */
+    int64_t content_len;            /* Content-Length header value */
+    int64_t consumed_content;       /* How many bytes of content have been read */
+    char *buf;                      /* Buffer for received data */
+    char *path_info;                /* PATH_INFO part of the URL */
+    int must_close;                 /* 1 if connection must be closed */
+    int in_error_handler;           /* 1 if in handler for user defined error pages */
+    int buf_size;                   /* Buffer size */
+    int request_len;                /* Size of the request + headers in a buffer */
+    int data_len;                   /* Total size of data in a buffer */
+    int status_code;                /* HTTP reply status code, e.g. 200 */
+    int throttle;                   /* Throttling, bytes/sec. <= 0 means no throttle */
+    time_t last_throttle_time;      /* Last time throttled data was sent */
+    int64_t last_throttle_bytes;    /* Bytes sent this second */
+    pthread_mutex_t mutex;          /* Used by mg_lock_connection/mg_unlock_connection to ensure atomic transmissions for websockets */
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+    void * lua_websocket_state;     /* Lua_State for a websocket connection */
+#endif
+};
+
+static pthread_key_t sTlsKey;  /* Thread local storage index */
+static int sTlsInit = 0;
+
+struct mg_workerTLS {
+    int is_master;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+    HANDLE pthread_cond_helper_mutex;
+#endif
+};
+
+/* Directory entry */
+struct de {
+    struct mg_connection *conn;
+    char *file_name;
+    struct file file;
+};
+
+#if defined(USE_WEBSOCKET)
+static int is_websocket_protocol(const struct mg_connection *conn);
+#else
+#define is_websocket_protocol(conn) (0)
+#endif
+
+int mg_atomic_inc(volatile int * addr)
+{
+    int ret;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+    ret = InterlockedIncrement((volatile unsigned int *) addr);
+#elif defined(__GNUC__)
+    ret = __sync_add_and_fetch(addr, 1);
+#else
+    ret = (++(*addr));
+#endif
+    return ret;
+}
+
+int mg_atomic_dec(volatile int * addr)
+{
+    int ret;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+    ret = InterlockedDecrement((volatile unsigned int *) addr);
+#elif defined(__GNUC__)
+    ret = __sync_sub_and_fetch(addr, 1);
+#else
+    ret = (--(*addr));
+#endif
+    return ret;
+}
+
+#if !defined(NO_THREAD_NAME)
+#if defined(_WIN32) && defined(_MSC_VER)
+/* Set the thread name for debugging purposes in Visual Studio
+   http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
+*/
+#pragma pack(push,8)
+typedef struct tagTHREADNAME_INFO
+{
+   DWORD dwType;     /* Must be 0x1000. */
+   LPCSTR szName;    /* Pointer to name (in user addr space). */
+   DWORD dwThreadID; /* Thread ID (-1=caller thread). */
+   DWORD dwFlags;    /* Reserved for future use, must be zero. */
+} THREADNAME_INFO;
+#pragma pack(pop)
+#elif defined(__linux__)
+#include <sys/prctl.h>
+#endif
+
+void mg_set_thread_name(const char* name)
+{
+    char threadName[16]; /* Max. thread length in Linux/OSX/.. */
+
+    if (snprintf(threadName, sizeof(threadName), "civetweb-%s", name)<0) return;
+    threadName[sizeof(threadName)-1] = 0;
+
+#if defined(_WIN32)
+#if defined(_MSC_VER)
+    /* Windows and Visual Studio Compiler */
+    __try
+    {
+        THREADNAME_INFO info;
+        info.dwType     = 0x1000;
+        info.szName     = threadName;
+        info.dwThreadID = -1;
+        info.dwFlags    = 0;
+
+        RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
+    }
+    __except(EXCEPTION_EXECUTE_HANDLER)
+    {
+    }
+#elif defined(__MINGW32__)
+   /* No option known to set thread name for MinGW */
+#endif
+#elif defined(__linux__)
+   /* Linux */
+   (void)prctl(PR_SET_NAME,threadName,0,0,0);
+#elif defined(__APPLE__) || defined(__MACH__)
+   /* OS X (TODO: test) */
+   (void)pthread_setname_np(threadName);
+#elif defined(BSD) || defined(__FreeBSD__) || defined(__OpenBSD__)
+   /* BSD (TODO: test) */
+   pthread_set_name_np(pthread_self(), threadName);
+#else
+   /* POSIX */
+   (void)pthread_setname_np(pthread_self(), threadName);
+#endif
+}
+#else /* !defined(NO_THREAD_NAME) */
+void mg_set_thread_name(const char* threadName) {}
+#endif
+
+#if defined(MG_LEGACY_INTERFACE)
+const char **mg_get_valid_option_names(void)
+{
+    static const char * data[2 * sizeof(config_options) / sizeof(config_options[0])] = {0};
+    int i;
+
+    for (i=0; config_options[i].name != NULL; i++) {
+        data[i * 2] = config_options[i].name;
+        data[i * 2 + 1] = config_options[i].default_value;
+    }
+
+    return data;
+}
+#endif
+
+const struct mg_option *mg_get_valid_options(void)
+{
+    return config_options;
+}
+
+
+static int is_file_in_memory(struct mg_connection *conn, const char *path,
+                             struct file *filep)
+{
+    size_t size = 0;
+    if ((filep->membuf = conn->ctx->callbacks.open_file == NULL ? NULL :
+                         conn->ctx->callbacks.open_file(conn, path, &size)) != NULL) {
+        /* NOTE: override filep->size only on success. Otherwise, it might
+           break constructs like if (!mg_stat() || !mg_fopen()) ... */
+        filep->size = size;
+    }
+    return filep->membuf != NULL;
+}
+
+static int is_file_opened(const struct file *filep)
+{
+    return filep->membuf != NULL || filep->fp != NULL;
+}
+
+static int mg_fopen(struct mg_connection *conn, const char *path,
+                    const char *mode, struct file *filep)
+{
+    if (!is_file_in_memory(conn, path, filep)) {
+#ifdef _WIN32
+        wchar_t wbuf[PATH_MAX], wmode[20];
+        to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
+        MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, ARRAY_SIZE(wmode));
+        filep->fp = _wfopen(wbuf, wmode);
+#else
+        filep->fp = fopen(path, mode);
+#endif
+    }
+
+    return is_file_opened(filep);
+}
+
+static void mg_fclose(struct file *filep)
+{
+    if (filep != NULL && filep->fp != NULL) {
+        fclose(filep->fp);
+    }
+}
+
+static void mg_strlcpy(register char *dst, register const char *src, size_t n)
+{
+    for (; *src != '\0' && n > 1; n--) {
+        *dst++ = *src++;
+    }
+    *dst = '\0';
+}
+
+static int lowercase(const char *s)
+{
+    return tolower(* (const unsigned char *) s);
+}
+
+int mg_strncasecmp(const char *s1, const char *s2, size_t len)
+{
+    int diff = 0;
+
+    if (len > 0)
+        do {
+            diff = lowercase(s1++) - lowercase(s2++);
+        } while (diff == 0 && s1[-1] != '\0' && --len > 0);
+
+    return diff;
+}
+
+static int mg_strcasecmp(const char *s1, const char *s2)
+{
+    int diff;
+
+    do {
+        diff = lowercase(s1++) - lowercase(s2++);
+    } while (diff == 0 && s1[-1] != '\0');
+
+    return diff;
+}
+
+static char * mg_strndup(const char *ptr, size_t len)
+{
+    char *p;
+
+    if ((p = (char *) mg_malloc(len + 1)) != NULL) {
+        mg_strlcpy(p, ptr, len + 1);
+    }
+
+    return p;
+}
+
+static char * mg_strdup(const char *str)
+{
+    return mg_strndup(str, strlen(str));
+}
+
+static const char *mg_strcasestr(const char *big_str, const char *small_str)
+{
+    int i, big_len = (int)strlen(big_str), small_len = (int)strlen(small_str);
+
+    for (i = 0; i <= big_len - small_len; i++) {
+        if (mg_strncasecmp(big_str + i, small_str, small_len) == 0) {
+            return big_str + i;
+        }
+    }
+
+    return NULL;
+}
+
+/* Like snprintf(), but never returns negative value, or a value
+   that is larger than a supplied buffer.
+   Thanks to Adam Zeldis to pointing snprintf()-caused vulnerability
+   in his audit report. */
+static int mg_vsnprintf(struct mg_connection *conn, char *buf, size_t buflen,
+                        const char *fmt, va_list ap)
+{
+    int n;
+
+    if (buflen == 0)
+        return 0;
+
+    n = vsnprintf(buf, buflen, fmt, ap);
+
+    if (n < 0) {
+        mg_cry(conn, "vsnprintf error");
+        n = 0;
+    } else if (n >= (int) buflen) {
+        mg_cry(conn, "truncating vsnprintf buffer: [%.*s]",
+               n > 200 ? 200 : n, buf);
+        n = (int) buflen - 1;
+    }
+    buf[n] = '\0';
+
+    return n;
+}
+
+static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
+                       PRINTF_FORMAT_STRING(const char *fmt), ...)
+PRINTF_ARGS(4, 5);
+
+static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
+                       const char *fmt, ...)
+{
+    va_list ap;
+    int n;
+
+    va_start(ap, fmt);
+    n = mg_vsnprintf(conn, buf, buflen, fmt, ap);
+    va_end(ap);
+
+    return n;
+}
+
+static int get_option_index(const char *name)
+{
+    int i;
+
+    for (i = 0; config_options[i].name != NULL; i++) {
+        if (strcmp(config_options[i].name, name) == 0) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+const char *mg_get_option(const struct mg_context *ctx, const char *name)
+{
+    int i;
+    if ((i = get_option_index(name)) == -1) {
+        return NULL;
+    } else if (ctx->config[i] == NULL) {
+        return "";
+    } else {
+        return ctx->config[i];
+    }
+}
+
+struct mg_context *mg_get_context(struct mg_connection * conn)
+{
+    return (conn == NULL) ? (struct mg_context *)NULL : (conn->ctx);
+}
+
+void *mg_get_user_data(struct mg_context *ctx)
+{
+    return (ctx == NULL) ? NULL : ctx->user_data;
+}
+
+size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl)
+{
+    size_t i;
+    for (i = 0; i < size && i < (size_t)ctx->num_listening_sockets; i++)
+    {
+        ssl[i] = ctx->listening_sockets[i].is_ssl;
+        ports[i] = ctx->listening_ports[i];
+    }
+    return i;
+}
+
+static void sockaddr_to_string(char *buf, size_t len,
+                               const union usa *usa)
+{
+    buf[0] = '\0';
+#if defined(USE_IPV6)
+    inet_ntop(usa->sa.sa_family, usa->sa.sa_family == AF_INET ?
+              (void *) &usa->sin.sin_addr :
+              (void *) &usa->sin6.sin6_addr, buf, len);
+#elif defined(_WIN32)
+    /* Only Windows Vista (and newer) have inet_ntop() */
+    mg_strlcpy(buf, inet_ntoa(usa->sin.sin_addr), len);
+#else
+    inet_ntop(usa->sa.sa_family, (void *) &usa->sin.sin_addr, buf, len);
+#endif
+}
+
+/* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be included in all responses other than 100, 101, 5xx. */
+static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
+{
+    struct tm *tm;
+
+    tm = gmtime(t);
+    if (tm != NULL) {
+        strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
+    } else {
+        mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
+        buf[buf_len - 1] = '\0';
+    }
+}
+
+/* Print error message to the opened error log stream. */
+void mg_cry(struct mg_connection *conn, const char *fmt, ...)
+{
+    char buf[MG_BUF_LEN], src_addr[IP_ADDR_STR_LEN];
+    va_list ap;
+    FILE *fp;
+    time_t timestamp;
+
+    va_start(ap, fmt);
+    IGNORE_UNUSED_RESULT(vsnprintf(buf, sizeof(buf), fmt, ap));
+    va_end(ap);
+
+    /* Do not lock when getting the callback value, here and below.
+       I suppose this is fine, since function cannot disappear in the
+       same way string option can. */
+    if (conn->ctx->callbacks.log_message == NULL ||
+        conn->ctx->callbacks.log_message(conn, buf) == 0) {
+        fp = conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL :
+             fopen(conn->ctx->config[ERROR_LOG_FILE], "a+");
+
+        if (fp != NULL) {
+            flockfile(fp);
+            timestamp = time(NULL);
+
+            sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
+            fprintf(fp, "[%010lu] [error] [client %s] ", (unsigned long) timestamp,
+                    src_addr);
+
+            if (conn->request_info.request_method != NULL) {
+                fprintf(fp, "%s %s: ", conn->request_info.request_method,
+                        conn->request_info.uri);
+            }
+
+            fprintf(fp, "%s", buf);
+            fputc('\n', fp);
+            funlockfile(fp);
+            fclose(fp);
+        }
+    }
+}
+
+/* Return fake connection structure. Used for logging, if connection
+   is not applicable at the moment of logging. */
+static struct mg_connection *fc(struct mg_context *ctx)
+{
+    static struct mg_connection fake_connection;
+    fake_connection.ctx = ctx;
+    return &fake_connection;
+}
+
+const char *mg_version(void)
+{
+    return CIVETWEB_VERSION;
+}
+
+struct mg_request_info *mg_get_request_info(struct mg_connection *conn)
+{
+    return &conn->request_info;
+}
+
+/* Skip the characters until one of the delimiters characters found.
+   0-terminate resulting word. Skip the delimiter and following whitespaces.
+   Advance pointer to buffer to the next word. Return found 0-terminated word.
+   Delimiters can be quoted with quotechar. */
+static char *skip_quoted(char **buf, const char *delimiters,
+                         const char *whitespace, char quotechar)
+{
+    char *p, *begin_word, *end_word, *end_whitespace;
+
+    begin_word = *buf;
+    end_word = begin_word + strcspn(begin_word, delimiters);
+
+    /* Check for quotechar */
+    if (end_word > begin_word) {
+        p = end_word - 1;
+        while (*p == quotechar) {
+            /* TODO (bel): it seems this code is never reached, so quotechar is actually
+               not needed - check if this code may be droped */
+
+            /* If there is anything beyond end_word, copy it */
+            if (*end_word == '\0') {
+                *p = '\0';
+                break;
+            } else {
+                size_t end_off = strcspn(end_word + 1, delimiters);
+                memmove (p, end_word, end_off + 1);
+                p += end_off; /* p must correspond to end_word - 1 */
+                end_word += end_off + 1;
+            }
+        }
+        for (p++; p < end_word; p++) {
+            *p = '\0';
+        }
+    }
+
+    if (*end_word == '\0') {
+        *buf = end_word;
+    } else {
+        end_whitespace = end_word + 1 + strspn(end_word + 1, whitespace);
+
+        for (p = end_word; p < end_whitespace; p++) {
+            *p = '\0';
+        }
+
+        *buf = end_whitespace;
+    }
+
+    return begin_word;
+}
+
+/* Simplified version of skip_quoted without quote char
+   and whitespace == delimiters */
+static char *skip(char **buf, const char *delimiters)
+{
+    return skip_quoted(buf, delimiters, delimiters, 0);
+}
+
+
+/* Return HTTP header value, or NULL if not found. */
+static const char *get_header(const struct mg_request_info *ri,
+                              const char *name)
+{
+    int i;
+
+    for (i = 0; i < ri->num_headers; i++)
+        if (!mg_strcasecmp(name, ri->http_headers[i].name))
+            return ri->http_headers[i].value;
+
+    return NULL;
+}
+
+const char *mg_get_header(const struct mg_connection *conn, const char *name)
+{
+    return get_header(&conn->request_info, name);
+}
+
+/* A helper function for traversing a comma separated list of values.
+   It returns a list pointer shifted to the next value, or NULL if the end
+   of the list found.
+   Value is stored in val vector. If value has form "x=y", then eq_val
+   vector is initialized to point to the "y" part, and val vector length
+   is adjusted to point only to "x". */
+static const char *next_option(const char *list, struct vec *val,
+                               struct vec *eq_val)
+{
+    if (list == NULL || *list == '\0') {
+        /* End of the list */
+        list = NULL;
+    } else {
+        val->ptr = list;
+        if ((list = strchr(val->ptr, ',')) != NULL) {
+            /* Comma found. Store length and shift the list ptr */
+            val->len = list - val->ptr;
+            list++;
+        } else {
+            /* This value is the last one */
+            list = val->ptr + strlen(val->ptr);
+            val->len = list - val->ptr;
+        }
+
+        if (eq_val != NULL) {
+            /* Value has form "x=y", adjust pointers and lengths
+               so that val points to "x", and eq_val points to "y". */
+            eq_val->len = 0;
+            eq_val->ptr = (const char *) memchr(val->ptr, '=', val->len);
+            if (eq_val->ptr != NULL) {
+                eq_val->ptr++;  /* Skip over '=' character */
+                eq_val->len = val->ptr + val->len - eq_val->ptr;
+                val->len = (eq_val->ptr - val->ptr) - 1;
+            }
+        }
+    }
+
+    return list;
+}
+
+/* Perform case-insensitive match of string against pattern */
+static int match_prefix(const char *pattern, int pattern_len, const char *str)
+{
+    const char *or_str;
+    int i, j, len, res;
+
+    if ((or_str = (const char *) memchr(pattern, '|', pattern_len)) != NULL) {
+        res = match_prefix(pattern, (int)(or_str - pattern), str);
+        return res > 0 ? res :
+               match_prefix(or_str + 1, (int)((pattern + pattern_len) - (or_str + 1)), str);
+    }
+
+    i = j = 0;
+    for (; i < pattern_len; i++, j++) {
+        if (pattern[i] == '?' && str[j] != '\0') {
+            continue;
+        } else if (pattern[i] == '$') {
+            return str[j] == '\0' ? j : -1;
+        } else if (pattern[i] == '*') {
+            i++;
+            if (pattern[i] == '*') {
+                i++;
+                len = (int) strlen(str + j);
+            } else {
+                len = (int) strcspn(str + j, "/");
+            }
+            if (i == pattern_len) {
+                return j + len;
+            }
+            do {
+                res = match_prefix(pattern + i, pattern_len - i, str + j + len);
+            } while (res == -1 && len-- > 0);
+            return res == -1 ? -1 : j + res + len;
+        } else if (lowercase(&pattern[i]) != lowercase(&str[j])) {
+            return -1;
+        }
+    }
+    return j;
+}
+
+/* HTTP 1.1 assumes keep alive if "Connection:" header is not set
+   This function must tolerate situations when connection info is not
+   set up, for example if request parsing failed. */
+static int should_keep_alive(const struct mg_connection *conn)
+{
+    const char *http_version = conn->request_info.http_version;
+    const char *header = mg_get_header(conn, "Connection");
+    if (conn->must_close ||
+        conn->status_code == 401 ||
+        mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 ||
+        (header != NULL && mg_strcasecmp(header, "keep-alive") != 0) ||
+        (header == NULL && http_version && 0!=strcmp(http_version, "1.1"))) {
+        return 0;
+    }
+    return 1;
+}
+
+static int should_decode_url(const struct mg_connection *conn)
+{
+    return (mg_strcasecmp(conn->ctx->config[DECODE_URL], "yes") == 0);
+}
+
+static const char *suggest_connection_header(const struct mg_connection *conn)
+{
+    return should_keep_alive(conn) ? "keep-alive" : "close";
+}
+
+static void handle_file_based_request(struct mg_connection *conn, const char *path, struct file *filep);
+static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep);
+
+static const char *mg_get_response_code_text(int response_code, struct mg_connection *conn)
+{
+    switch (response_code)
+    {
+    /* RFC2616 Section 10.1 - Informational 1xx */
+    case 100: return "Continue"; /* RFC2616 Section 10.1.1 */
+    case 101: return "Switching Protocols"; /* RFC2616 Section 10.1.2 */
+    case 102: return "Processing"; /* RFC2518 Section 10.1 */
+
+    /* RFC2616 Section 10.2 - Successful 2xx */
+    case 200: return "OK"; /* RFC2616 Section 10.2.1 */
+    case 201: return "Created"; /* RFC2616 Section 10.2.2 */
+    case 202: return "Accepted"; /* RFC2616 Section 10.2.3 */
+    case 203: return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */
+    case 204: return "No Content"; /* RFC2616 Section 10.2.5 */
+    case 205: return "Reset Content"; /* RFC2616 Section 10.2.6 */
+    case 206: return "Partial Content"; /* RFC2616 Section 10.2.7 */
+    case 207: return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1 */
+
+    /* RFC2616 Section 10.3 - Redirection 3xx */
+    case 300: return "Multiple Choices"; /* RFC2616 Section 10.3.1 */
+    case 301: return "Moved Permanently"; /* RFC2616 Section 10.3.2 */
+    case 302: return "Found"; /* RFC2616 Section 10.3.3 */
+    case 303: return "See Other"; /* RFC2616 Section 10.3.4 */
+    case 304: return "Not Modified"; /* RFC2616 Section 10.3.5 */
+    case 305: return "Use Proxy"; /* RFC2616 Section 10.3.6 */
+    case 307: return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */
+
+    /* RFC2616 Section 10.4 - Client Error 4xx */
+    case 400: return "Bad Request"; /* RFC2616 Section 10.4.1 */
+    case 401: return "Unauthorized"; /* RFC2616 Section 10.4.2 */
+    case 402: return "Payment Required"; /* RFC2616 Section 10.4.3 */
+    case 403: return "Forbidden"; /* RFC2616 Section 10.4.4 */
+    case 404: return "Not Found"; /* RFC2616 Section 10.4.5 */
+    case 405: return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */
+    case 406: return "Not Acceptable"; /* RFC2616 Section 10.4.7 */
+    case 407: return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */
+    case 408: return "Request Time-out"; /* RFC2616 Section 10.4.9 */
+    case 409: return "Conflict"; /* RFC2616 Section 10.4.10 */
+    case 410: return "Gone"; /* RFC2616 Section 10.4.11 */
+    case 411: return "Length Required"; /* RFC2616 Section 10.4.12 */
+    case 412: return "Precondition Failed"; /* RFC2616 Section 10.4.13 */
+    case 413: return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */
+    case 414: return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */
+    case 415: return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */
+    case 416: return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17 */
+    case 417: return "Expectation Failed"; /* RFC2616 Section 10.4.18 */
+    case 422: return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918 Section 11.2 */
+    case 423: return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */
+    case 424: return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918 Section 11.4 */
+    case 428: return "Precondition Required"; /* RFC 6585, Section 3 */
+    case 429: return "Too Many Requests"; /* RFC 6585, Section 4 */
+    case 431: return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */
+
+    /* RFC2616 Section 10.5 - Server Error 5xx */
+    case 500: return "Internal Server Error"; /* RFC2616 Section 10.5.1 */
+    case 501: return "Not Implemented"; /* RFC2616 Section 10.5.2 */
+    case 502: return "Bad Gateway"; /* RFC2616 Section 10.5.3 */
+    case 503: return "Service Unavailable"; /* RFC2616 Section 10.5.4 */
+    case 504: return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */
+    case 505: return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */
+    case 507: return "Insufficient Storage"; /* RFC2518 Section 10.6, , RFC4918 Section 11.5 */
+    case 511: return "Network Authentication Required"; /* RFC 6585, Section 6 */
+
+    /* Other RFCs */
+    case 426: return "Upgrade Required"; /* RFC 2817 */
+
+    /* Return codes from non normative RFCs: */
+    /* Informative and experimental RFCs, "de facto" standards due to common use, ... */
+    case 208: return "Already Reported"; /* RFC5842 Section 7.1 */
+    case 226: return "IM used"; /* RFC3229 Section 10.4.1 */
+    case 308: return "Permanent Redirect"; /* RFC7238 Section 3 */
+    case 418: return "I am a teapot"; /* RFC2324 Section 2.3.2 */
+    case 419: return "Authentication Timeout"; /* common use */
+    case 451: return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05, Section 3 */
+    case 506: return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */
+    case 508: return "Loop Detected"; /* RFC5842 Section 7.1 */
+    case 510: return "Not Extended"; /* RFC 2774, Section 7 */
+
+    default:
+        /* This error code is unknown. This should not happen. */
+        if (conn) {
+            mg_cry(conn, "Unknown HTTP response code: %u", response_code);
+        }
+
+        /* Return at least a category according to RFC 2616 Section 10. */
+        if (response_code>=100 && response_code<200) {
+            /* Unknown informational status code */
+            return "Information";
+        }
+        if (response_code>=200 && response_code<300) {
+            /* Unknown success code */
+            return "Success";
+        }
+        if (response_code>=300 && response_code<400) {
+            /* Unknown redirection code */
+            return "Redirection";
+        }
+        if (response_code>=400 && response_code<500) {
+            /* Unknown request error code */
+            return "Client Error";
+        }
+        if (response_code>=500 && response_code<600) {
+            /* Unknown server error code */
+            return "Server Error";
+        }
+
+        /* Response code not even within reasonable range */
+        return "";
+    }
+}
+
+
+static void send_http_error(struct mg_connection *, int, const char *,
+                            PRINTF_FORMAT_STRING(const char *fmt), ...)
+PRINTF_ARGS(4, 5);
+
+
+static void send_http_error(struct mg_connection *conn, int status,
+                            const char *reason, const char *fmt, ...)
+{
+    char buf[MG_BUF_LEN];
+    va_list ap;
+    int len = 0, i, page_handler_found, scope;
+    char date[64];
+    time_t curtime = time(NULL);
+    const char *error_handler = NULL;
+    struct file error_page_file = STRUCT_FILE_INITIALIZER;
+    const char *error_page_file_ext, *tstr;
+
+    if (!reason) {
+        reason = mg_get_response_code_text(status, conn);
+    }
+
+    conn->status_code = status;
+    if (conn->in_error_handler ||
+        conn->ctx->callbacks.http_error == NULL ||
+        conn->ctx->callbacks.http_error(conn, status)) {
+
+        if (!conn->in_error_handler) {
+            /* Send user defined error pages, if defined */
+            error_handler = conn->ctx->config[ERROR_PAGES];
+            error_page_file_ext = conn->ctx->config[INDEX_FILES];
+            page_handler_found = 0;
+            if (error_handler != NULL) {
+                for (scope=1; (scope<=3) && !page_handler_found; scope++) {
+                    switch (scope) {
+                    case 1:
+                        len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%03u.", error_handler, status);
+                        break;
+                    case 2:
+                        len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%01uxx.", error_handler, status/100);
+                        break;
+                    default:
+                        len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror.", error_handler);
+                        break;
+                    }
+                    tstr = strchr(error_page_file_ext, '.');
+                    while (tstr) {
+                        for (i=1; i<32 && tstr[i]!=0 && tstr[i]!=','; i++) buf[len+i-1]=tstr[i];
+                        buf[len+i-1]=0;
+                        if (mg_stat(conn, buf, &error_page_file)) {
+                            page_handler_found = 1;
+                            break;
+                        }
+                        tstr = strchr(tstr+i, '.');
+                    }
+                }
+            }
+
+            if (page_handler_found) {
+                conn->in_error_handler = 1;
+                handle_file_based_request(conn, buf, &error_page_file);
+                conn->in_error_handler = 0;
+                return;
+            }
+        }
+
+        buf[0] = '\0';
+        gmt_time_string(date, sizeof(date), &curtime);
+
+        /* Errors 1xx, 204 and 304 MUST NOT send a body */
+        if (status > 199 && status != 204 && status != 304) {
+            len = mg_snprintf(conn, buf, sizeof(buf)-1, "Error %d: %s", status, reason);
+            buf[len] = '\n';
+            len++;
+            buf[len] = 0;
+
+            va_start(ap, fmt);
+            len += mg_vsnprintf(conn, buf + len, sizeof(buf) - len, fmt, ap);
+            va_end(ap);
+        }
+        DEBUG_TRACE("[%s]", buf);
+
+        mg_printf(conn, "HTTP/1.1 %d %s\r\n"
+                        "Content-Length: %d\r\n"
+                        "Date: %s\r\n"
+                        "Connection: %s\r\n\r\n",
+                        status, reason, len, date,
+                        suggest_connection_header(conn));
+        conn->num_bytes_sent += mg_printf(conn, "%s", buf);
+    }
+}
+
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+static int pthread_mutex_init(pthread_mutex_t *mutex, void *unused)
+{
+    (void) unused;
+    *mutex = CreateMutex(NULL, FALSE, NULL);
+    return *mutex == NULL ? -1 : 0;
+}
+
+static int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+    return CloseHandle(*mutex) == 0 ? -1 : 0;
+}
+
+static int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+    return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
+}
+
+static int pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+    switch (WaitForSingleObject(*mutex, 0)) {
+        case WAIT_OBJECT_0:
+            return 0;
+        case WAIT_TIMEOUT:
+            return -2; /* EBUSY */
+    }
+    return -1;
+}
+
+static int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+    return ReleaseMutex(*mutex) == 0 ? -1 : 0;
+}
+
+#ifndef WIN_PTHREADS_TIME_H
+static int clock_gettime(clockid_t clk_id, struct timespec *tp)
+{
+    FILETIME ft;
+    ULARGE_INTEGER li;
+    BOOL ok = FALSE;
+    double d;
+    static double perfcnt_per_sec = 0.0;
+
+    if (tp) {
+        if (clk_id == CLOCK_REALTIME) {
+            GetSystemTimeAsFileTime(&ft);
+            li.LowPart = ft.dwLowDateTime;
+            li.HighPart = ft.dwHighDateTime;
+            li.QuadPart -= 116444736000000000; /* 1.1.1970 in filedate */
+            tp->tv_sec = (time_t)(li.QuadPart / 10000000);
+            tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
+            ok = TRUE;
+        } else if (clk_id == CLOCK_MONOTONIC) {
+            if (perfcnt_per_sec == 0.0) {
+                QueryPerformanceFrequency((LARGE_INTEGER *) &li);
+                perfcnt_per_sec = 1.0 / li.QuadPart;
+            }
+            if (perfcnt_per_sec != 0.0) {
+                QueryPerformanceCounter((LARGE_INTEGER *) &li);
+                d = li.QuadPart * perfcnt_per_sec;
+                tp->tv_sec = (time_t)d;
+                d -= tp->tv_sec;
+                tp->tv_nsec = (long)(d*1.0E9);
+                ok = TRUE;
+            }
+        }
+    }
+
+    return ok ? 0 : -1;
+}
+#endif
+
+static int pthread_cond_init(pthread_cond_t *cv, const void *unused)
+{
+    (void) unused;
+    InitializeCriticalSection(&cv->threadIdSec);
+    cv->waitingthreadcount = 0;
+    cv->waitingthreadhdls = (pthread_t *) mg_calloc(MAX_WORKER_THREADS, sizeof(pthread_t));
+    return (cv->waitingthreadhdls!=NULL) ? 0 : -1;
+}
+
+static int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec * abstime)
+{
+    struct mg_workerTLS * tls = (struct mg_workerTLS *)TlsGetValue(sTlsKey);
+    int ok;
+    struct timespec tsnow;
+    int64_t nsnow, nswaitabs, nswaitrel;
+    DWORD mswaitrel;
+
+    EnterCriticalSection(&cv->threadIdSec);
+    assert(cv->waitingthreadcount < MAX_WORKER_THREADS);
+    cv->waitingthreadhdls[cv->waitingthreadcount] = tls->pthread_cond_helper_mutex;
+    cv->waitingthreadcount++;
+    LeaveCriticalSection(&cv->threadIdSec);
+
+    if (abstime) {
+        clock_gettime(CLOCK_REALTIME, &tsnow);
+        nsnow = (((uint64_t)tsnow.tv_sec)*1000000000) + tsnow.tv_nsec;
+        nswaitabs = (((uint64_t)abstime->tv_sec)*1000000000) + abstime->tv_nsec;
+        nswaitrel = nswaitabs - nsnow;
+        if (nswaitrel<0) nswaitrel=0;
+        mswaitrel = (DWORD)(nswaitrel / 1000000);
+    } else {
+        mswaitrel = INFINITE;
+    }
+
+    pthread_mutex_unlock(mutex);
+    ok = (WAIT_OBJECT_0 == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel));
+    pthread_mutex_lock(mutex);
+
+    return ok ? 0 : -1;
+}
+
+static int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex)
+{
+    return pthread_cond_timedwait(cv, mutex, NULL);
+}
+
+static int pthread_cond_signal(pthread_cond_t *cv)
+{
+    int i;
+    HANDLE wkup = NULL;
+    BOOL ok = FALSE;
+
+    EnterCriticalSection(&cv->threadIdSec);
+    if (cv->waitingthreadcount) {
+        wkup = cv->waitingthreadhdls[0];
+        ok = SetEvent(wkup);
+
+        for (i=1; i<cv->waitingthreadcount; i++) {
+            cv->waitingthreadhdls[i-1] = cv->waitingthreadhdls[i];
+        }
+        cv->waitingthreadcount--;
+
+        assert(ok);
+    }
+    LeaveCriticalSection(&cv->threadIdSec);
+
+    return ok ? 0 : 1;
+}
+
+static int pthread_cond_broadcast(pthread_cond_t *cv)
+{
+    EnterCriticalSection(&cv->threadIdSec);
+    while (cv->waitingthreadcount) {
+        pthread_cond_signal(cv);
+    }
+    LeaveCriticalSection(&cv->threadIdSec);
+
+    return 0;
+}
+
+static int pthread_cond_destroy(pthread_cond_t *cv)
+{
+    EnterCriticalSection(&cv->threadIdSec);
+    assert(cv->waitingthreadcount==0);
+    mg_free(cv->waitingthreadhdls);
+    cv->waitingthreadhdls = 0;
+    LeaveCriticalSection(&cv->threadIdSec);
+    DeleteCriticalSection(&cv->threadIdSec);
+
+    return 0;
+}
+
+/* For Windows, change all slashes to backslashes in path names. */
+static void change_slashes_to_backslashes(char *path)
+{
+    int i;
+
+    for (i = 0; path[i] != '\0'; i++) {
+        if (path[i] == '/')
+            path[i] = '\\';
+        /* i > 0 check is to preserve UNC paths, like \\server\file.txt */
+        if (path[i] == '\\' && i > 0)
+            while (path[i + 1] == '\\' || path[i + 1] == '/')
+                (void) memmove(path + i + 1,
+                               path + i + 2, strlen(path + i + 1));
+    }
+}
+
+/* Encode 'path' which is assumed UTF-8 string, into UNICODE string.
+   wbuf and wbuf_len is a target buffer and its length. */
+static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len)
+{
+    char buf[PATH_MAX], buf2[PATH_MAX];
+
+    mg_strlcpy(buf, path, sizeof(buf));
+    change_slashes_to_backslashes(buf);
+
+    /* Convert to Unicode and back. If doubly-converted string does not
+       match the original, something is fishy, reject. */
+    memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
+    MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
+    WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
+                        NULL, NULL);
+    if (strcmp(buf, buf2) != 0) {
+        wbuf[0] = L'\0';
+    }
+}
+
+#if defined(_WIN32_WCE)
+static time_t time(time_t *ptime)
+{
+    time_t t;
+    SYSTEMTIME st;
+    FILETIME ft;
+
+    GetSystemTime(&st);
+    SystemTimeToFileTime(&st, &ft);
+    t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime);
+
+    if (ptime != NULL) {
+        *ptime = t;
+    }
+
+    return t;
+}
+
+static struct tm *localtime(const time_t *ptime, struct tm *ptm)
+{
+    int64_t t = ((int64_t) *ptime) * RATE_DIFF + EPOCH_DIFF;
+    FILETIME ft, lft;
+    SYSTEMTIME st;
+    TIME_ZONE_INFORMATION tzinfo;
+
+    if (ptm == NULL) {
+        return NULL;
+    }
+
+    * (int64_t *) &ft = t;
+    FileTimeToLocalFileTime(&ft, &lft);
+    FileTimeToSystemTime(&lft, &st);
+    ptm->tm_year = st.wYear - 1900;
+    ptm->tm_mon = st.wMonth - 1;
+    ptm->tm_wday = st.wDayOfWeek;
+    ptm->tm_mday = st.wDay;
+    ptm->tm_hour = st.wHour;
+    ptm->tm_min = st.wMinute;
+    ptm->tm_sec = st.wSecond;
+    ptm->tm_yday = 0; /* hope nobody uses this */
+    ptm->tm_isdst =
+        GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT ? 1 : 0;
+
+    return ptm;
+}
+
+static struct tm *gmtime(const time_t *ptime, struct tm *ptm)
+{
+    /* FIXME(lsm): fix this. */
+    return localtime(ptime, ptm);
+}
+
+static size_t strftime(char *dst, size_t dst_size, const char *fmt,
+                       const struct tm *tm)
+{
+    (void) snprintf(dst, dst_size, "implement strftime() for WinCE");
+    return 0;
+}
+#endif
+
+/* Windows happily opens files with some garbage at the end of file name.
+   For example, fopen("a.cgi    ", "r") on Windows successfully opens
+   "a.cgi", despite one would expect an error back.
+   This function returns non-0 if path ends with some garbage. */
+static int path_cannot_disclose_cgi(const char *path)
+{
+    static const char *allowed_last_characters = "_-";
+    int last = path[strlen(path) - 1];
+    return isalnum(last) || strchr(allowed_last_characters, last) != NULL;
+}
+
+static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
+{
+    wchar_t wbuf[PATH_MAX];
+    WIN32_FILE_ATTRIBUTE_DATA info;
+
+    if (!is_file_in_memory(conn, path, filep)) {
+        to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
+        if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
+            filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
+            filep->modification_time = SYS2UNIX_TIME(
+                                           info.ftLastWriteTime.dwLowDateTime,
+                                           info.ftLastWriteTime.dwHighDateTime);
+            filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+            /* If file name is fishy, reset the file structure and return
+               error.
+               Note it is important to reset, not just return the error, cause
+               functions like is_file_opened() check the struct. */
+            if (!filep->is_directory && !path_cannot_disclose_cgi(path)) {
+                memset(filep, 0, sizeof(*filep));
+            }
+        }
+    }
+
+    return filep->membuf != NULL || filep->modification_time != 0;
+}
+
+static int mg_remove(const char *path)
+{
+    wchar_t wbuf[PATH_MAX];
+    to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
+    return DeleteFileW(wbuf) ? 0 : -1;
+}
+
+static int mg_mkdir(const char *path, int mode)
+{
+    char buf[PATH_MAX];
+    wchar_t wbuf[PATH_MAX];
+
+    (void) mode;
+    mg_strlcpy(buf, path, sizeof(buf));
+    change_slashes_to_backslashes(buf);
+
+    (void) MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, ARRAY_SIZE(wbuf));
+
+    return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
+}
+
+/* Implementation of POSIX opendir/closedir/readdir for Windows. */
+static DIR * opendir(const char *name)
+{
+    DIR *dir = NULL;
+    wchar_t wpath[PATH_MAX];
+    DWORD attrs;
+
+    if (name == NULL) {
+        SetLastError(ERROR_BAD_ARGUMENTS);
+    } else if ((dir = (DIR *) mg_malloc(sizeof(*dir))) == NULL) {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    } else {
+        to_unicode(name, wpath, ARRAY_SIZE(wpath));
+        attrs = GetFileAttributesW(wpath);
+        if (attrs != 0xFFFFFFFF &&
+            ((attrs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)) {
+            (void) wcscat(wpath, L"\\*");
+            dir->handle = FindFirstFileW(wpath, &dir->info);
+            dir->result.d_name[0] = '\0';
+        } else {
+            mg_free(dir);
+            dir = NULL;
+        }
+    }
+
+    return dir;
+}
+
+static int closedir(DIR *dir)
+{
+    int result = 0;
+
+    if (dir != NULL) {
+        if (dir->handle != INVALID_HANDLE_VALUE)
+            result = FindClose(dir->handle) ? 0 : -1;
+
+        mg_free(dir);
+    } else {
+        result = -1;
+        SetLastError(ERROR_BAD_ARGUMENTS);
+    }
+
+    return result;
+}
+
+static struct dirent *readdir(DIR *dir)
+{
+    struct dirent *result = 0;
+
+    if (dir) {
+        if (dir->handle != INVALID_HANDLE_VALUE) {
+            result = &dir->result;
+            (void) WideCharToMultiByte(CP_UTF8, 0,
+                                       dir->info.cFileName, -1, result->d_name,
+                                       sizeof(result->d_name), NULL, NULL);
+
+            if (!FindNextFileW(dir->handle, &dir->info)) {
+                (void) FindClose(dir->handle);
+                dir->handle = INVALID_HANDLE_VALUE;
+            }
+
+        } else {
+            SetLastError(ERROR_FILE_NOT_FOUND);
+        }
+    } else {
+        SetLastError(ERROR_BAD_ARGUMENTS);
+    }
+
+    return result;
+}
+
+#ifndef HAVE_POLL
+static int poll(struct pollfd *pfd, int n, int milliseconds)
+{
+    struct timeval tv;
+    fd_set set;
+    int i, result;
+    SOCKET maxfd = 0;
+
+    tv.tv_sec = milliseconds / 1000;
+    tv.tv_usec = (milliseconds % 1000) * 1000;
+    FD_ZERO(&set);
+
+    for (i = 0; i < n; i++) {
+        FD_SET((SOCKET) pfd[i].fd, &set);
+        pfd[i].revents = 0;
+
+        if (pfd[i].fd > maxfd) {
+            maxfd = pfd[i].fd;
+        }
+    }
+
+    if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) {
+        for (i = 0; i < n; i++) {
+            if (FD_ISSET(pfd[i].fd, &set)) {
+                pfd[i].revents = POLLIN;
+            }
+        }
+    }
+
+    return result;
+}
+#endif /* HAVE_POLL */
+
+static void set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */)
+{
+    (void) conn; /* Unused. */
+    (void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
+}
+
+int mg_start_thread(mg_thread_func_t f, void *p)
+{
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+    /* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 */
+    return ((_beginthread((void (__cdecl *)(void *)) f, USE_STACK_SIZE, p) == ((uintptr_t)(-1L))) ? -1 : 0);
+#else
+    return ((_beginthread((void (__cdecl *)(void *)) f, 0, p) == ((uintptr_t)(-1L))) ? -1 : 0);
+#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
+}
+
+/* Start a thread storing the thread context. */
+
+static int mg_start_thread_with_id(unsigned (__stdcall *f)(void *), void *p,
+                                   pthread_t *threadidptr)
+{
+    uintptr_t uip;
+    HANDLE threadhandle;
+    int result = -1;
+
+    uip = _beginthreadex(NULL, 0, (unsigned (__stdcall *)(void *)) f, p, 0,
+                         NULL);
+    threadhandle = (HANDLE) uip;
+    if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) {
+        *threadidptr = threadhandle;
+        result = 0;
+    }
+
+    return result;
+}
+
+/* Wait for a thread to finish. */
+
+static int mg_join_thread(pthread_t threadid)
+{
+    int result;
+    DWORD dwevent;
+
+    result = -1;
+    dwevent = WaitForSingleObject(threadid, INFINITE);
+    if (dwevent == WAIT_FAILED) {
+        int err;
+
+        err = GetLastError();
+        DEBUG_TRACE("WaitForSingleObject() failed, error %d", err);
+    } else {
+        if (dwevent == WAIT_OBJECT_0) {
+            CloseHandle(threadid);
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+static HANDLE dlopen(const char *dll_name, int flags)
+{
+    wchar_t wbuf[PATH_MAX];
+    (void) flags;
+    to_unicode(dll_name, wbuf, ARRAY_SIZE(wbuf));
+    return LoadLibraryW(wbuf);
+}
+
+static int dlclose(void *handle)
+{
+    int result;
+
+    if (FreeLibrary((HMODULE) handle) != 0) {
+        result = 0;
+    } else {
+        result = -1;
+    }
+
+    return result;
+}
+
+#if !defined(NO_CGI)
+#define SIGKILL 0
+static int kill(pid_t pid, int sig_num)
+{
+    (void) TerminateProcess(pid, sig_num);
+    (void) CloseHandle(pid);
+    return 0;
+}
+
+static void trim_trailing_whitespaces(char *s)
+{
+    char *e = s + strlen(s) - 1;
+    while (e > s && isspace(* (unsigned char *) e)) {
+        *e-- = '\0';
+    }
+}
+
+static pid_t spawn_process(struct mg_connection *conn, const char *prog,
+                           char *envblk, char *envp[], int fdin,
+                           int fdout, const char *dir)
+{
+    HANDLE me;
+    char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
+         cmdline[PATH_MAX], buf[PATH_MAX];
+    struct file file = STRUCT_FILE_INITIALIZER;
+    STARTUPINFOA si;
+    PROCESS_INFORMATION pi = { 0 };
+
+    (void) envp;
+
+    memset(&si, 0, sizeof(si));
+    si.cb = sizeof(si);
+
+    /* TODO(lsm): redirect CGI errors to the error log file */
+    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+    si.wShowWindow = SW_HIDE;
+
+    me = GetCurrentProcess();
+    DuplicateHandle(me, (HANDLE) _get_osfhandle(fdin), me,
+                    &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
+    DuplicateHandle(me, (HANDLE) _get_osfhandle(fdout), me,
+                    &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
+
+    /* If CGI file is a script, try to read the interpreter line */
+    interp = conn->ctx->config[CGI_INTERPRETER];
+    if (interp == NULL) {
+        buf[0] = buf[1] = '\0';
+
+        /* Read the first line of the script into the buffer */
+        snprintf(cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
+        if (mg_fopen(conn, cmdline, "r", &file)) {
+            p = (char *) file.membuf;
+            mg_fgets(buf, sizeof(buf), &file, &p);
+            mg_fclose(&file);
+            buf[sizeof(buf) - 1] = '\0';
+        }
+
+        if (buf[0] == '#' && buf[1] == '!') {
+            trim_trailing_whitespaces(buf + 2);
+        } else {
+            buf[2] = '\0';
+        }
+        interp = buf + 2;
+    }
+
+    if (interp[0] != '\0') {
+        GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL);
+        interp = full_interp;
+    }
+    GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL);
+
+    mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s\"%s\\%s\"",
+                interp, interp[0] == '\0' ? "" : " ", full_dir, prog);
+
+    DEBUG_TRACE("Running [%s]", cmdline);
+    if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
+                       CREATE_NEW_PROCESS_GROUP, envblk, NULL, &si, &pi) == 0) {
+        mg_cry(conn, "%s: CreateProcess(%s): %ld",
+               __func__, cmdline, ERRNO);
+        pi.hProcess = (pid_t) -1;
+    }
+
+    (void) CloseHandle(si.hStdOutput);
+    (void) CloseHandle(si.hStdInput);
+    if (pi.hThread != NULL)
+        (void) CloseHandle(pi.hThread);
+
+    return (pid_t) pi.hProcess;
+}
+#endif /* !NO_CGI */
+
+static int set_non_blocking_mode(SOCKET sock)
+{
+    unsigned long on = 1;
+    return ioctlsocket(sock, FIONBIO, &on);
+}
+
+#else
+static int mg_stat(struct mg_connection *conn, const char *path,
+                   struct file *filep)
+{
+    struct stat st;
+
+    if (!is_file_in_memory(conn, path, filep) && !stat(path, &st)) {
+        filep->size = st.st_size;
+        filep->modification_time = st.st_mtime;
+        filep->is_directory = S_ISDIR(st.st_mode);
+    } else {
+        filep->modification_time = (time_t) 0;
+    }
+
+    return filep->membuf != NULL || filep->modification_time != (time_t) 0;
+}
+
+static void set_close_on_exec(int fd, struct mg_connection *conn /* may be null */)
+{
+    if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
+        if (conn) {
+            mg_cry(conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, strerror(ERRNO));
+        }
+    }
+}
+
+int mg_start_thread(mg_thread_func_t func, void *param)
+{
+    pthread_t thread_id;
+    pthread_attr_t attr;
+    int result;
+
+    (void) pthread_attr_init(&attr);
+    (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+    /* Compile-time option to control stack size,
+       e.g. -DUSE_STACK_SIZE=16384 */
+    (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
+#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
+
+    result = pthread_create(&thread_id, &attr, func, param);
+    pthread_attr_destroy(&attr);
+
+    return result;
+}
+
+/* Start a thread storing the thread context. */
+
+static int mg_start_thread_with_id(mg_thread_func_t func, void *param, pthread_t *threadidptr)
+{
+    pthread_t thread_id;
+    pthread_attr_t attr;
+    int result;
+
+    (void) pthread_attr_init(&attr);
+
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+    /* Compile-time option to control stack size,
+       e.g. -DUSE_STACK_SIZE=16384 */
+    (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
+#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */
+
+    result = pthread_create(&thread_id, &attr, func, param);
+    pthread_attr_destroy(&attr);
+    if ((result == 0) && (threadidptr != NULL)) {
+        *threadidptr = thread_id;
+    }
+    return result;
+}
+
+/* Wait for a thread to finish. */
+
+static int mg_join_thread(pthread_t threadid)
+{
+    int result;
+
+    result = pthread_join(threadid, NULL);
+    return result;
+}
+
+#ifndef NO_CGI
+static pid_t spawn_process(struct mg_connection *conn, const char *prog,
+                           char *envblk, char *envp[], int fdin,
+                           int fdout, const char *dir)
+{
+    pid_t pid;
+    const char *interp;
+
+    (void) envblk;
+
+    if ((pid = fork()) == -1) {
+        /* Parent */
+        send_http_error(conn, 500, NULL,
+            "Error: Creating CGI process\nfork(): %s", strerror(ERRNO));
+    } else if (pid == 0) {
+        /* Child */
+        if (chdir(dir) != 0) {
+            mg_cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO));
+        } else if (dup2(fdin, 0) == -1) {
+            mg_cry(conn, "%s: dup2(%d, 0): %s", __func__, fdin, strerror(ERRNO));
+        } else if (dup2(fdout, 1) == -1) {
+            mg_cry(conn, "%s: dup2(%d, 1): %s", __func__, fdout, strerror(ERRNO));
+        } else {
+            /* Not redirecting stderr to stdout, to avoid output being littered
+               with the error messages. */
+            (void) close(fdin);
+            (void) close(fdout);
+
+            /* After exec, all signal handlers are restored to their default
+               values, with one exception of SIGCHLD. According to
+               POSIX.1-2001 and Linux's implementation, SIGCHLD's handler will
+               leave unchanged after exec if it was set to be ignored. Restore
+               it to default action. */
+            signal(SIGCHLD, SIG_DFL);
+
+            interp = conn->ctx->config[CGI_INTERPRETER];
+            if (interp == NULL) {
+                (void) execle(prog, prog, NULL, envp);
+                mg_cry(conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO));
+            } else {
+                (void) execle(interp, interp, prog, NULL, envp);
+                mg_cry(conn, "%s: execle(%s %s): %s", __func__, interp, prog,
+                       strerror(ERRNO));
+            }
+        }
+        exit(EXIT_FAILURE);
+    }
+
+    return pid;
+}
+#endif /* !NO_CGI */
+
+static int set_non_blocking_mode(SOCKET sock)
+{
+    int flags;
+
+    flags = fcntl(sock, F_GETFL, 0);
+    (void) fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+
+    return 0;
+}
+#endif /* _WIN32 */
+
+/* Write data to the IO channel - opened file descriptor, socket or SSL
+   descriptor. Return number of bytes written. */
+static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
+{
+    int64_t sent;
+    int n, k;
+
+    (void) ssl;  /* Get rid of warning */
+    sent = 0;
+    while (sent < len) {
+
+        /* How many bytes we send in this iteration */
+        k = len - sent > INT_MAX ? INT_MAX : (int) (len - sent);
+
+#ifndef NO_SSL
+        if (ssl != NULL) {
+            n = SSL_write(ssl, buf + sent, k);
+        } else
+#endif
+            if (fp != NULL) {
+                n = (int) fwrite(buf + sent, 1, (size_t) k, fp);
+                if (ferror(fp))
+                    n = -1;
+            } else {
+                n = send(sock, buf + sent, (size_t) k, MSG_NOSIGNAL);
+            }
+
+        if (n <= 0)
+            break;
+
+        sent += n;
+    }
+
+    return sent;
+}
+
+/* Read from IO channel - opened file descriptor, socket, or SSL descriptor.
+   Return negative value on error, or number of bytes read on success. */
+static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
+{
+    int nread;
+
+    if (fp != NULL) {
+        /* Use read() instead of fread(), because if we're reading from the
+           CGI pipe, fread() may block until IO buffer is filled up. We cannot
+           afford to block and must pass all read bytes immediately to the
+           client. */
+        nread = read(fileno(fp), buf, (size_t) len);
+#ifndef NO_SSL
+    } else if (conn->ssl != NULL) {
+        nread = SSL_read(conn->ssl, buf, len);
+#endif
+    } else {
+        nread = recv(conn->client.sock, buf, (size_t) len, 0);
+    }
+
+    return conn->ctx->stop_flag ? -1 : nread;
+}
+
+static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
+{
+    int n, nread = 0;
+
+    while (len > 0 && conn->ctx->stop_flag == 0) {
+        n = pull(fp, conn, buf + nread, len);
+        if (n < 0) {
+            nread = n;  /* Propagate the error */
+            break;
+        } else if (n == 0) {
+            break;  /* No more data to read */
+        } else {
+            conn->consumed_content += n;
+            nread += n;
+            len -= n;
+        }
+    }
+
+    return nread;
+}
+
+int mg_read(struct mg_connection *conn, void *buf, size_t len)
+{
+    int64_t n, buffered_len, nread;
+    int64_t len64 = (int64_t)(len > INT_MAX ? INT_MAX : len); /* since the return value is int, we may not read more bytes */
+    const char *body;
+
+    /* If Content-Length is not set for a PUT or POST request, read until socket is closed */
+    if (conn->consumed_content == 0 && conn->content_len == -1) {
+        conn->content_len = INT64_MAX;
+        conn->must_close = 1;
+    }
+
+    nread = 0;
+    if (conn->consumed_content < conn->content_len) {
+        /* Adjust number of bytes to read. */
+        int64_t left_to_read = conn->content_len - conn->consumed_content;
+        if (left_to_read < len64) {
+            /* Do not reade more than the total content length of the request. */
+            len64 = left_to_read;
+        }
+
+        /* Return buffered data */
+        buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len - conn->consumed_content;
+        if (buffered_len > 0) {
+            if (len64 < buffered_len) {
+                buffered_len = len64;
+            }
+            body = conn->buf + conn->request_len + conn->consumed_content;
+            memcpy(buf, body, (size_t) buffered_len);
+            len64 -= buffered_len;
+            conn->consumed_content += buffered_len;
+            nread += buffered_len;
+            buf = (char *) buf + buffered_len;
+        }
+
+        /* We have returned all buffered data. Read new data from the remote
+           socket. */
+        if ((n = pull_all(NULL, conn, (char *) buf, (int)len64)) >= 0) {
+            nread += n;
+        } else {
+            nread = (nread > 0 ? nread : n);
+        }
+    }
+    return (int)nread;
+}
+
+int mg_write(struct mg_connection *conn, const void *buf, size_t len)
+{
+    time_t now;
+    int64_t n, total, allowed;
+
+    if (conn->throttle > 0) {
+        if ((now = time(NULL)) != conn->last_throttle_time) {
+            conn->last_throttle_time = now;
+            conn->last_throttle_bytes = 0;
+        }
+        allowed = conn->throttle - conn->last_throttle_bytes;
+        if (allowed > (int64_t) len) {
+            allowed = len;
+        }
+        if ((total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
+                          (int64_t) allowed)) == allowed) {
+            buf = (char *) buf + total;
+            conn->last_throttle_bytes += total;
+            while (total < (int64_t) len && conn->ctx->stop_flag == 0) {
+                allowed = conn->throttle > (int64_t) len - total ?
+                          (int64_t) len - total : conn->throttle;
+                if ((n = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
+                              (int64_t) allowed)) != allowed) {
+                    break;
+                }
+                sleep(1);
+                conn->last_throttle_bytes = allowed;
+                conn->last_throttle_time = time(NULL);
+                buf = (char *) buf + n;
+                total += n;
+            }
+        }
+    } else {
+        total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
+                     (int64_t) len);
+    }
+    return (int) total;
+}
+
+/* Alternative alloc_vprintf() for non-compliant C runtimes */
+static int alloc_vprintf2(char **buf, const char *fmt, va_list ap)
+{
+    va_list ap_copy;
+    int size = MG_BUF_LEN;
+    int len = -1;
+
+    *buf = NULL;
+    while (len == -1) {
+        if (*buf) mg_free(*buf);
+        *buf = (char *)mg_malloc(size *= 4);
+        if (!*buf) break;
+        va_copy(ap_copy, ap);
+        len = vsnprintf(*buf, size, fmt, ap_copy);
+        va_end(ap_copy);
+    }
+
+    return len;
+}
+
+/* Print message to buffer. If buffer is large enough to hold the message,
+   return buffer. If buffer is to small, allocate large enough buffer on heap,
+   and return allocated buffer. */
+static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap)
+{
+    va_list ap_copy;
+    int len;
+
+    /* Windows is not standard-compliant, and vsnprintf() returns -1 if
+       buffer is too small. Also, older versions of msvcrt.dll do not have
+       _vscprintf().  However, if size is 0, vsnprintf() behaves correctly.
+       Therefore, we make two passes: on first pass, get required message
+       length.
+       On second pass, actually print the message. */
+    va_copy(ap_copy, ap);
+    len = vsnprintf(NULL, 0, fmt, ap_copy);
+    va_end(ap_copy);
+
+    if (len < 0) {
+        /* C runtime is not standard compliant, vsnprintf() returned -1.
+           Switch to alternative code path that uses incremental allocations.
+        */
+        va_copy(ap_copy, ap);
+        len = alloc_vprintf2(buf, fmt, ap);
+        va_end(ap_copy);
+    } else if (len > (int) size &&
+               (size = len + 1) > 0 &&
+               (*buf = (char *) mg_malloc(size)) == NULL) {
+        len = -1;  /* Allocation failed, mark failure */
+    } else {
+        va_copy(ap_copy, ap);
+        IGNORE_UNUSED_RESULT(vsnprintf(*buf, size, fmt, ap_copy));
+        va_end(ap_copy);
+    }
+
+    return len;
+}
+
+int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap)
+{
+    char mem[MG_BUF_LEN], *buf = mem;
+    int len;
+
+    if ((len = alloc_vprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
+        len = mg_write(conn, buf, (size_t) len);
+    }
+    if (buf != mem && buf != NULL) {
+        mg_free(buf);
+    }
+
+    return len;
+}
+
+int mg_printf(struct mg_connection *conn, const char *fmt, ...)
+{
+    va_list ap;
+    int result;
+
+    va_start(ap, fmt);
+    result = mg_vprintf(conn, fmt, ap);
+    va_end(ap);
+
+    return result;
+}
+
+int mg_url_decode(const char *src, int src_len, char *dst,
+                  int dst_len, int is_form_url_encoded)
+{
+    int i, j, a, b;
+#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
+
+    for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
+        if (i < src_len - 2 && src[i] == '%' &&
+            isxdigit(* (const unsigned char *) (src + i + 1)) &&
+            isxdigit(* (const unsigned char *) (src + i + 2))) {
+            a = tolower(* (const unsigned char *) (src + i + 1));
+            b = tolower(* (const unsigned char *) (src + i + 2));
+            dst[j] = (char) ((HEXTOI(a) << 4) | HEXTOI(b));
+            i += 2;
+        } else if (is_form_url_encoded && src[i] == '+') {
+            dst[j] = ' ';
+        } else {
+            dst[j] = src[i];
+        }
+    }
+
+    dst[j] = '\0'; /* Null-terminate the destination */
+
+    return i >= src_len ? j : -1;
+}
+
+int mg_get_var(const char *data, size_t data_len, const char *name,
+               char *dst, size_t dst_len)
+{
+    return mg_get_var2(data,data_len,name,dst,dst_len,0);
+}
+
+int mg_get_var2(const char *data, size_t data_len, const char *name,
+                char *dst, size_t dst_len, size_t occurrence)
+{
+    const char *p, *e, *s;
+    size_t name_len;
+    int len;
+
+    if (dst == NULL || dst_len == 0) {
+        len = -2;
+    } else if (data == NULL || name == NULL || data_len == 0) {
+        len = -1;
+        dst[0] = '\0';
+    } else {
+        name_len = strlen(name);
+        e = data + data_len;
+        len = -1;
+        dst[0] = '\0';
+
+        /* data is "var1=val1&var2=val2...". Find variable first */
+        for (p = data; p + name_len < e; p++) {
+            if ((p == data || p[-1] == '&') && p[name_len] == '=' &&
+                !mg_strncasecmp(name, p, name_len) && 0 == occurrence--) {
+
+                /* Point p to variable value */
+                p += name_len + 1;
+
+                /* Point s to the end of the value */
+                s = (const char *) memchr(p, '&', (size_t)(e - p));
+                if (s == NULL) {
+                    s = e;
+                }
+                assert(s >= p);
+
+                /* Decode variable into destination buffer */
+                len = mg_url_decode(p, (int)(s - p), dst, (int)dst_len, 1);
+
+                /* Redirect error code from -1 to -2 (destination buffer too
+                   small). */
+                if (len == -1) {
+                    len = -2;
+                }
+                break;
+            }
+        }
+    }
+
+    return len;
+}
+
+int mg_get_cookie(const char *cookie_header, const char *var_name,
+                  char *dst, size_t dst_size)
+{
+    const char *s, *p, *end;
+    int name_len, len = -1;
+
+    if (dst == NULL || dst_size == 0) {
+        len = -2;
+    } else if (var_name == NULL || (s = cookie_header) == NULL) {
+        len = -1;
+        dst[0] = '\0';
+    } else {
+        name_len = (int) strlen(var_name);
+        end = s + strlen(s);
+        dst[0] = '\0';
+
+        for (; (s = mg_strcasestr(s, var_name)) != NULL; s += name_len) {
+    

<TRUNCATED>

[18/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/pubsub_admin_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/pubsub_admin_impl.c b/pubsub/pubsub_admin_udp_mc/private/src/pubsub_admin_impl.c
deleted file mode 100644
index 1fbdb08..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/pubsub_admin_impl.c
+++ /dev/null
@@ -1,1039 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * pubsub_admin_impl.c
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifndef ANDROID
-#include <ifaddrs.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include "constants.h"
-#include "utils.h"
-#include "hash_map.h"
-#include "array_list.h"
-#include "bundle_context.h"
-#include "bundle.h"
-#include "service_reference.h"
-#include "service_registration.h"
-#include "log_helper.h"
-#include "log_service.h"
-#include "celix_threads.h"
-#include "service_factory.h"
-
-#include "pubsub_admin_impl.h"
-#include "topic_subscription.h"
-#include "topic_publication.h"
-#include "pubsub_endpoint.h"
-#include "subscriber.h"
-#include "pubsub_admin_match.h"
-
-static const char *DEFAULT_MC_IP = "224.100.1.1";
-static char *DEFAULT_MC_PREFIX = "224.100";
-
-static celix_status_t pubsubAdmin_getIpAddress(const char* interface, char** ip);
-static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-
-static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc);
-static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication);
-static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication);
-
-celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*admin = calloc(1, sizeof(**admin));
-
-	if (!*admin) {
-		return CELIX_ENOMEM;
-	}
-
-	char *mc_ip = NULL;
-	char *if_ip = NULL;
-	int sendSocket = -1;
-
-	if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
-		logHelper_start((*admin)->loghelper);
-	}
-	const char *mc_ip_prop = NULL;
-	bundleContext_getProperty(context,PSA_IP , &mc_ip_prop);
-	if(mc_ip_prop) {
-		mc_ip = strdup(mc_ip_prop);
-	}
-
-#ifndef ANDROID
-	if (mc_ip == NULL) {
-		const char *mc_prefix = NULL;
-		const char *interface = NULL;
-		int b0 = 0, b1 = 0, b2 = 0, b3 = 0;
-		bundleContext_getProperty(context,PSA_MULTICAST_IP_PREFIX , &mc_prefix);
-		if(mc_prefix == NULL) {
-			mc_prefix = DEFAULT_MC_PREFIX;
-		}
-
-		bundleContext_getProperty(context, PSA_ITF, &interface);
-		if (pubsubAdmin_getIpAddress(interface, &if_ip) != CELIX_SUCCESS) {
-			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: Could not retrieve IP address for interface %s", interface);
-		}
-
-		printf("IP Detected : %s\n", if_ip);
-		if(if_ip && sscanf(if_ip, "%i.%i.%i.%i", &b0, &b1, &b2, &b3) != 4) {
-			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: Could not parse IP address %s", if_ip);
-			b2 = 1;
-			b3 = 1;
-		}
-
-		asprintf(&mc_ip, "%s.%d.%d",mc_prefix, b2, b3);
-
-		sendSocket = socket(AF_INET, SOCK_DGRAM, 0);
-		if(sendSocket == -1) {
-			perror("pubsubAdmin_create:socket");
-			status = CELIX_SERVICE_EXCEPTION;
-		}
-
-		if(status == CELIX_SUCCESS){
-			char loop = 1;
-			if(setsockopt(sendSocket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != 0) {
-				perror("pubsubAdmin_create:setsockopt(IP_MULTICAST_LOOP)");
-				status = CELIX_SERVICE_EXCEPTION;
-			}
-		}
-
-		if(status == CELIX_SUCCESS){
-			struct in_addr multicast_interface;
-			inet_aton(if_ip, &multicast_interface);
-			if(setsockopt(sendSocket,  IPPROTO_IP, IP_MULTICAST_IF, &multicast_interface, sizeof(multicast_interface)) != 0) {
-				perror("pubsubAdmin_create:setsockopt(IP_MULTICAST_IF)");
-				status = CELIX_SERVICE_EXCEPTION;
-			}
-		}
-
-	}
-
-
-	if(status != CELIX_SUCCESS){
-		logHelper_stop((*admin)->loghelper);
-		logHelper_destroy(&((*admin)->loghelper));
-		if(sendSocket >=0){
-			close(sendSocket);
-		}
-		if(if_ip != NULL){
-			free(if_ip);
-		}
-		if(mc_ip != NULL){
-			free(mc_ip);
-		}
-		return status;
-	}
-	else{
-		(*admin)->sendSocket = sendSocket;
-	}
-
-#endif
-
-	(*admin)->bundle_context= context;
-	(*admin)->localPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-	(*admin)->subscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-	(*admin)->pendingSubscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-	(*admin)->externalPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-	(*admin)->topicSubscriptionsPerSerializer = hashMap_create(NULL, NULL, NULL, NULL);
-	(*admin)->topicPublicationsPerSerializer  = hashMap_create(NULL, NULL, NULL, NULL);
-	arrayList_create(&((*admin)->noSerializerSubscriptions));
-	arrayList_create(&((*admin)->noSerializerPublications));
-	arrayList_create(&((*admin)->serializerList));
-
-	celixThreadMutex_create(&(*admin)->localPublicationsLock, NULL);
-	celixThreadMutex_create(&(*admin)->subscriptionsLock, NULL);
-	celixThreadMutex_create(&(*admin)->externalPublicationsLock, NULL);
-	celixThreadMutex_create(&(*admin)->serializerListLock, NULL);
-	celixThreadMutex_create(&(*admin)->usedSerializersLock, NULL);
-
-	celixThreadMutexAttr_create(&(*admin)->noSerializerPendingsAttr);
-	celixThreadMutexAttr_settype(&(*admin)->noSerializerPendingsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
-	celixThreadMutex_create(&(*admin)->noSerializerPendingsLock, &(*admin)->noSerializerPendingsAttr);
-
-	celixThreadMutexAttr_create(&(*admin)->pendingSubscriptionsAttr);
-	celixThreadMutexAttr_settype(&(*admin)->pendingSubscriptionsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
-	celixThreadMutex_create(&(*admin)->pendingSubscriptionsLock, &(*admin)->pendingSubscriptionsAttr);
-
-	if (if_ip != NULL) {
-		logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_UDP_MC: Using %s as interface for multicast communication", if_ip);
-		(*admin)->ifIpAddress = if_ip;
-	} else {
-		(*admin)->ifIpAddress = strdup("127.0.0.1");
-	}
-
-	if (mc_ip != NULL) {
-		logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_UDP_MC: Using %s for service annunciation", mc_ip);
-		(*admin)->mcIpAddress = mc_ip;
-	}
-	else {
-		logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: No IP address for service annunciation set. Using %s", DEFAULT_MC_IP);
-		(*admin)->mcIpAddress = strdup(DEFAULT_MC_IP);
-	}
-
-	return status;
-}
-
-
-celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin)
-{
-	celix_status_t status = CELIX_SUCCESS;
-
-	free(admin->mcIpAddress);
-	free(admin->ifIpAddress);
-
-	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
-	hash_map_iterator_pt iter = hashMapIterator_create(admin->pendingSubscriptions);
-	while(hashMapIterator_hasNext(iter)){
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-		free((char*)hashMapEntry_getKey(entry));
-		arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(admin->pendingSubscriptions,false,false);
-	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
-
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-	hashMap_destroy(admin->subscriptions,false,false);
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	celixThreadMutex_lock(&admin->localPublicationsLock);
-	hashMap_destroy(admin->localPublications,true,false);
-	celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-	celixThreadMutex_lock(&admin->externalPublicationsLock);
-	iter = hashMapIterator_create(admin->externalPublications);
-	while(hashMapIterator_hasNext(iter)){
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-		free((char*)hashMapEntry_getKey(entry));
-		arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(admin->externalPublications,false,false);
-	celixThreadMutex_unlock(&admin->externalPublicationsLock);
-
-	celixThreadMutex_lock(&admin->serializerListLock);
-	arrayList_destroy(admin->serializerList);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-	celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-	arrayList_destroy(admin->noSerializerSubscriptions);
-	arrayList_destroy(admin->noSerializerPublications);
-	celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-
-	celixThreadMutex_lock(&admin->usedSerializersLock);
-
-	iter = hashMapIterator_create(admin->topicSubscriptionsPerSerializer);
-	while(hashMapIterator_hasNext(iter)){
-		arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(admin->topicSubscriptionsPerSerializer,false,false);
-
-	iter = hashMapIterator_create(admin->topicPublicationsPerSerializer);
-	while(hashMapIterator_hasNext(iter)){
-		arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(admin->topicPublicationsPerSerializer,false,false);
-
-	celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-	celixThreadMutex_destroy(&admin->usedSerializersLock);
-	celixThreadMutex_destroy(&admin->serializerListLock);
-
-	celixThreadMutexAttr_destroy(&admin->noSerializerPendingsAttr);
-	celixThreadMutex_destroy(&admin->noSerializerPendingsLock);
-
-	celixThreadMutex_destroy(&admin->pendingSubscriptionsLock);
-	celixThreadMutexAttr_destroy(&admin->pendingSubscriptionsAttr);
-
-	celixThreadMutex_destroy(&admin->subscriptionsLock);
-	celixThreadMutex_destroy(&admin->localPublicationsLock);
-	celixThreadMutex_destroy(&admin->externalPublicationsLock);
-
-	logHelper_stop(admin->loghelper);
-
-	logHelper_destroy(&admin->loghelper);
-
-	free(admin);
-
-	return status;
-}
-
-static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-
-	topic_subscription_pt any_sub = hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
-
-	if(any_sub==NULL){
-
-		int i;
-		pubsub_serializer_service_t *best_serializer = NULL;
-		if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
-			status = pubsub_topicSubscriptionCreate(admin->bundle_context, admin->ifIpAddress, PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, PUBSUB_ANY_SUB_TOPIC, best_serializer, &any_sub);
-		}
-		else{
-			printf("PSA_UDP_MC: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
-			celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-			arrayList_add(admin->noSerializerSubscriptions,subEP);
-			celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-		}
-
-		if (status == CELIX_SUCCESS){
-
-			/* Connect all internal publishers */
-			celixThreadMutex_lock(&admin->localPublicationsLock);
-			hash_map_iterator_pt lp_iter =hashMapIterator_create(admin->localPublications);
-			while(hashMapIterator_hasNext(lp_iter)){
-				service_factory_pt factory = (service_factory_pt)hashMapIterator_nextValue(lp_iter);
-				topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
-				array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
-
-				if(topic_publishers!=NULL){
-					for(i=0;i<arrayList_size(topic_publishers);i++){
-						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
-						if(pubEP->endpoint !=NULL){
-							status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
-						}
-					}
-					arrayList_destroy(topic_publishers);
-				}
-			}
-			hashMapIterator_destroy(lp_iter);
-			celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-			/* Connect also all external publishers */
-			celixThreadMutex_lock(&admin->externalPublicationsLock);
-			hash_map_iterator_pt extp_iter =hashMapIterator_create(admin->externalPublications);
-			while(hashMapIterator_hasNext(extp_iter)){
-				array_list_pt ext_pub_list = (array_list_pt)hashMapIterator_nextValue(extp_iter);
-				if(ext_pub_list!=NULL){
-					for(i=0;i<arrayList_size(ext_pub_list);i++){
-						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
-						if(pubEP->endpoint !=NULL){
-							status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
-						}
-					}
-				}
-			}
-			hashMapIterator_destroy(extp_iter);
-			celixThreadMutex_unlock(&admin->externalPublicationsLock);
-
-
-			pubsub_topicSubscriptionAddSubscriber(any_sub,subEP);
-
-			status += pubsub_topicSubscriptionStart(any_sub);
-
-		}
-
-		if (status == CELIX_SUCCESS){
-			hashMap_put(admin->subscriptions,strdup(PUBSUB_ANY_SUB_TOPIC),any_sub);
-			connectTopicPubSubToSerializer(admin, best_serializer, any_sub, false);
-		}
-
-	}
-
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	return status;
-}
-
-celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_UDP_MC: Received subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope,subEP->topic);
-
-	if(strcmp(subEP->topic,PUBSUB_ANY_SUB_TOPIC)==0){
-		return pubsubAdmin_addAnySubscription(admin,subEP);
-	}
-
-	/* Check if we already know some publisher about this topic, otherwise let's put the subscription in the pending hashmap */
-	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-	celixThreadMutex_lock(&admin->localPublicationsLock);
-	celixThreadMutex_lock(&admin->externalPublicationsLock);
-
-	char* scope_topic = createScopeTopicKey(subEP->scope,subEP->topic);
-
-	service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
-	array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
-
-	if(factory==NULL && ext_pub_list==NULL){ //No (local or external) publishers yet for this topic
-		pubsubAdmin_addSubscriptionToPendingList(admin,subEP);
-	}
-	else{
-		int i;
-		topic_subscription_pt subscription = hashMap_get(admin->subscriptions, scope_topic);
-
-		if(subscription == NULL) {
-			pubsub_serializer_service_t *best_serializer = NULL;
-			if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
-				status += pubsub_topicSubscriptionCreate(admin->bundle_context,admin->ifIpAddress, subEP->scope, subEP->topic, best_serializer, &subscription);
-			}
-			else{
-				printf("PSA_UDP_MC: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
-				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-				arrayList_add(admin->noSerializerSubscriptions,subEP);
-				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-			}
-
-			if (status==CELIX_SUCCESS){
-
-				/* Try to connect internal publishers */
-				if(factory!=NULL){
-					topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
-					array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
-
-					if(topic_publishers!=NULL){
-						for(i=0;i<arrayList_size(topic_publishers);i++){
-							pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
-							if(pubEP->endpoint !=NULL){
-								status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
-							}
-						}
-						arrayList_destroy(topic_publishers);
-					}
-
-				}
-
-				/* Look also for external publishers */
-				if(ext_pub_list!=NULL){
-					for(i=0;i<arrayList_size(ext_pub_list);i++){
-						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
-						if(pubEP->endpoint !=NULL){
-							status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
-						}
-					}
-				}
-
-				pubsub_topicSubscriptionAddSubscriber(subscription,subEP);
-
-				status += pubsub_topicSubscriptionStart(subscription);
-
-			}
-
-			if(status==CELIX_SUCCESS){
-
-				hashMap_put(admin->subscriptions,strdup(scope_topic),subscription);
-
-				connectTopicPubSubToSerializer(admin, best_serializer, subscription, false);
-			}
-		}
-
-		if (status == CELIX_SUCCESS){
-			pubsub_topicIncreaseNrSubscribers(subscription);
-		}
-	}
-
-	free(scope_topic);
-	celixThreadMutex_unlock(&admin->externalPublicationsLock);
-	celixThreadMutex_unlock(&admin->localPublicationsLock);
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_UDP_MC: Removing subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope, subEP->topic);
-
-	char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
-
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-	topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
-	if(sub!=NULL){
-		pubsub_topicDecreaseNrSubscribers(sub);
-		if(pubsub_topicGetNrSubscribers(sub) == 0) {
-			status = pubsub_topicSubscriptionRemoveSubscriber(sub,subEP);
-		}
-	}
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	if(sub==NULL){
-		/* Maybe the endpoint was pending */
-		celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-		if(!arrayList_removeElement(admin->noSerializerSubscriptions, subEP)){
-			status = CELIX_ILLEGAL_STATE;
-		}
-		celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-	}
-
-	free(scope_topic);
-
-
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_UDP_MC: Received publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->scope, pubEP->topic);
-
-	const char* fwUUID = NULL;
-
-	bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
-	if(fwUUID==NULL){
-		printf("PSA_UDP_MC: Cannot retrieve fwUUID.\n");
-		return CELIX_INVALID_BUNDLE_CONTEXT;
-	}
-	char* scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
-
-	if ((strcmp(pubEP->frameworkUUID, fwUUID) == 0) && (pubEP->endpoint == NULL)) {
-
-		celixThreadMutex_lock(&admin->localPublicationsLock);
-
-		service_factory_pt factory = (service_factory_pt) hashMap_get(admin->localPublications, scope_topic);
-
-		if (factory == NULL) {
-			topic_publication_pt pub = NULL;
-			pubsub_serializer_service_t *best_serializer = NULL;
-			if( (status=pubsubAdmin_getBestSerializer(admin, pubEP, &best_serializer)) == CELIX_SUCCESS){
-				status = pubsub_topicPublicationCreate(admin->sendSocket, pubEP, best_serializer, admin->mcIpAddress, &pub);
-			}
-			else{
-				printf("PSA_UDP_MC: Cannot find a serializer for publishing topic %s. Adding it to pending list.\n", pubEP->topic);
-				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-				arrayList_add(admin->noSerializerPublications,pubEP);
-				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-			}
-
-			if (status == CELIX_SUCCESS) {
-				status = pubsub_topicPublicationStart(admin->bundle_context, pub, &factory);
-				if (status == CELIX_SUCCESS && factory != NULL) {
-					hashMap_put(admin->localPublications, strdup(scope_topic), factory);
-					connectTopicPubSubToSerializer(admin, best_serializer, pub, true);
-				}
-			} else {
-				printf("PSA_UDP_MC: Cannot create a topicPublication for scope=%s, topic=%s (bundle %ld).\n", pubEP->scope, pubEP->topic, pubEP->serviceID);
-			}
-		} else {
-			//just add the new EP to the list
-			topic_publication_pt pub = (topic_publication_pt) factory->handle;
-			pubsub_topicPublicationAddPublisherEP(pub, pubEP);
-		}
-
-		celixThreadMutex_unlock(&admin->localPublicationsLock);
-	}
-	else{
-
-		celixThreadMutex_lock(&admin->externalPublicationsLock);
-		array_list_pt ext_pub_list = (array_list_pt) hashMap_get(admin->externalPublications, scope_topic);
-		if (ext_pub_list == NULL) {
-			arrayList_create(&ext_pub_list);
-			hashMap_put(admin->externalPublications, strdup(scope_topic), ext_pub_list);
-		}
-
-		arrayList_add(ext_pub_list, pubEP);
-
-		celixThreadMutex_unlock(&admin->externalPublicationsLock);
-	}
-
-	/* Re-evaluate the pending subscriptions */
-	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
-
-	hash_map_entry_pt pendingSub = hashMap_getEntry(admin->pendingSubscriptions, scope_topic);
-	if (pendingSub != NULL) { //There were pending subscription for the just published topic. Let's connect them.
-		char* topic = (char*) hashMapEntry_getKey(pendingSub);
-		array_list_pt pendingSubList = (array_list_pt) hashMapEntry_getValue(pendingSub);
-		int i;
-		for (i = 0; i < arrayList_size(pendingSubList); i++) {
-			pubsub_endpoint_pt subEP = (pubsub_endpoint_pt) arrayList_get(pendingSubList, i);
-			pubsubAdmin_addSubscription(admin, subEP);
-		}
-		hashMap_remove(admin->pendingSubscriptions, scope_topic);
-		arrayList_clear(pendingSubList);
-		arrayList_destroy(pendingSubList);
-		free(topic);
-	}
-
-	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
-
-	/* Connect the new publisher to the subscription for his topic, if there is any */
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-
-	topic_subscription_pt sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, scope_topic);
-	if (sub != NULL && pubEP->endpoint != NULL) {
-		pubsub_topicSubscriptionAddConnectPublisherToPendingList(sub, pubEP->endpoint);
-	}
-
-	/* And check also for ANY subscription */
-	topic_subscription_pt any_sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, PUBSUB_ANY_SUB_TOPIC);
-	if (any_sub != NULL && pubEP->endpoint != NULL) {
-		pubsub_topicSubscriptionAddConnectPublisherToPendingList(any_sub, pubEP->endpoint);
-	}
-
-	free(scope_topic);
-
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
-	celix_status_t status = CELIX_SUCCESS;
-	int count = 0;
-
-	printf("PSA_UDP_MC: Removing publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->scope, pubEP->topic);
-
-	const char* fwUUID = NULL;
-
-	bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
-	if(fwUUID==NULL){
-		printf("PSA_UDP_MC: Cannot retrieve fwUUID.\n");
-		return CELIX_INVALID_BUNDLE_CONTEXT;
-	}
-	char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
-
-	if(strcmp(pubEP->frameworkUUID,fwUUID)==0){
-
-		celixThreadMutex_lock(&admin->localPublicationsLock);
-		service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
-		if(factory!=NULL){
-			topic_publication_pt pub = (topic_publication_pt)factory->handle;
-			pubsub_topicPublicationRemovePublisherEP(pub,pubEP);
-		}
-		celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-		if(factory==NULL){
-			/* Maybe the endpoint was pending */
-			celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-			if(!arrayList_removeElement(admin->noSerializerPublications, pubEP)){
-				status = CELIX_ILLEGAL_STATE;
-			}
-			celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-		}
-
-	}
-	else{
-
-		celixThreadMutex_lock(&admin->externalPublicationsLock);
-		array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
-		if(ext_pub_list!=NULL){
-			int i;
-			bool found = false;
-			for(i=0;!found && i<arrayList_size(ext_pub_list);i++){
-				pubsub_endpoint_pt p  = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
-				found = pubsubEndpoint_equals(pubEP,p);
-				if (found){
-					arrayList_remove(ext_pub_list,i);
-				}
-			}
-			// Check if there are more publishers on the same endpoint (happens when 1 celix-instance with multiple bundles publish in same topic)
-			for(i=0; i<arrayList_size(ext_pub_list);i++) {
-				pubsub_endpoint_pt p  = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
-				if (strcmp(pubEP->endpoint,p->endpoint) == 0) {
-					count++;
-				}
-			}
-
-			if(arrayList_size(ext_pub_list)==0){
-				hash_map_entry_pt entry = hashMap_getEntry(admin->externalPublications,scope_topic);
-				char* topic = (char*)hashMapEntry_getKey(entry);
-				array_list_pt list = (array_list_pt)hashMapEntry_getValue(entry);
-				hashMap_remove(admin->externalPublications,topic);
-				arrayList_destroy(list);
-				free(topic);
-			}
-		}
-
-		celixThreadMutex_unlock(&admin->externalPublicationsLock);
-	}
-
-	/* Check if this publisher was connected to one of our subscribers*/
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-
-	topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
-	if(sub!=NULL && pubEP->endpoint!=NULL && count == 0){
-		pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(sub,pubEP->endpoint);
-	}
-
-	/* And check also for ANY subscription */
-	topic_subscription_pt any_sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
-	if(any_sub!=NULL && pubEP->endpoint!=NULL && count == 0){
-		pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(any_sub,pubEP->endpoint);
-	}
-
-	free(scope_topic);
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char *scope, char* topic){
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_UDP_MC: Closing all publications for scope=%s,topic=%s\n", scope, topic);
-
-	celixThreadMutex_lock(&admin->localPublicationsLock);
-	char* scope_topic =createScopeTopicKey(scope, topic);
-	hash_map_entry_pt pubsvc_entry = (hash_map_entry_pt)hashMap_getEntry(admin->localPublications,scope_topic);
-	if(pubsvc_entry!=NULL){
-		char* key = (char*)hashMapEntry_getKey(pubsvc_entry);
-		service_factory_pt factory= (service_factory_pt)hashMapEntry_getValue(pubsvc_entry);
-		topic_publication_pt pub = (topic_publication_pt)factory->handle;
-		status += pubsub_topicPublicationStop(pub);
-		disconnectTopicPubSubFromSerializer(admin, pub, true);
-		status += pubsub_topicPublicationDestroy(pub);
-		hashMap_remove(admin->localPublications,scope_topic);
-		free(key);
-		free(factory);
-	}
-	free(scope_topic);
-	celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char *scope, char* topic){
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_UDP_MC: Closing all subscriptions\n");
-
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-	char* scope_topic =createScopeTopicKey(scope, topic);
-	hash_map_entry_pt sub_entry = (hash_map_entry_pt)hashMap_getEntry(admin->subscriptions,scope_topic);
-	if(sub_entry!=NULL){
-		char* topic = (char*)hashMapEntry_getKey(sub_entry);
-
-		topic_subscription_pt ts = (topic_subscription_pt)hashMapEntry_getValue(sub_entry);
-		status += pubsub_topicSubscriptionStop(ts);
-		disconnectTopicPubSubFromSerializer(admin, ts, false);
-		status += pubsub_topicSubscriptionDestroy(ts);
-		hashMap_remove(admin->subscriptions,topic);
-		free(topic);
-
-	}
-	free(scope_topic);
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	return status;
-
-}
-
-
-#ifndef ANDROID
-static celix_status_t pubsubAdmin_getIpAddress(const char* interface, char** ip) {
-	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
-	struct ifaddrs *ifaddr, *ifa;
-	char host[NI_MAXHOST];
-
-	if (getifaddrs(&ifaddr) != -1)
-	{
-		for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
-		{
-			if (ifa->ifa_addr == NULL)
-				continue;
-
-			if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
-				if (interface == NULL) {
-					*ip = strdup(host);
-					status = CELIX_SUCCESS;
-				}
-				else if (strcmp(ifa->ifa_name, interface) == 0) {
-					*ip = strdup(host);
-					status = CELIX_SUCCESS;
-				}
-			}
-		}
-
-		freeifaddrs(ifaddr);
-	}
-
-	return status;
-}
-#endif
-
-static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	char* scope_topic =createScopeTopicKey(subEP->scope, subEP->topic);
-	array_list_pt pendingListPerTopic = hashMap_get(admin->pendingSubscriptions,scope_topic);
-	if(pendingListPerTopic==NULL){
-		arrayList_create(&pendingListPerTopic);
-		hashMap_put(admin->pendingSubscriptions,strdup(scope_topic),pendingListPerTopic);
-	}
-	arrayList_add(pendingListPerTopic,subEP);
-	free(scope_topic);
-
-	return status;
-}
-
-
-celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service){
-	/* Assumption: serializers are all available at startup.
-	 * If a new (possibly better) serializer is installed and started, already created topic_publications/subscriptions will not be destroyed and recreated */
-
-	celix_status_t status = CELIX_SUCCESS;
-	int i=0;
-
-	const char *serType = NULL;
-	serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
-	if(serType == NULL){
-		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
-		return CELIX_SERVICE_EXCEPTION;
-	}
-
-	pubsub_admin_pt admin = (pubsub_admin_pt)handle;
-	celixThreadMutex_lock(&admin->serializerListLock);
-	arrayList_add(admin->serializerList, reference);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-	/* Now let's re-evaluate the pending */
-	celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-
-	for(i=0;i<arrayList_size(admin->noSerializerSubscriptions);i++){
-		pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerSubscriptions,i);
-		pubsub_serializer_service_t *best_serializer = NULL;
-		pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
-		if(best_serializer != NULL){ /* Finally we have a valid serializer! */
-			pubsubAdmin_addSubscription(admin, ep);
-		}
-	}
-
-	for(i=0;i<arrayList_size(admin->noSerializerPublications);i++){
-		pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerPublications,i);
-		pubsub_serializer_service_t *best_serializer = NULL;
-		pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
-		if(best_serializer != NULL){ /* Finally we have a valid serializer! */
-			pubsubAdmin_addPublication(admin, ep);
-		}
-	}
-
-	celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-
-	printf("PSA_UDP_MC: %s serializer added\n",serType);
-
-	return status;
-}
-
-celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service){
-
-	pubsub_admin_pt admin = (pubsub_admin_pt)handle;
-	int i=0, j=0;
-	const char *serType = NULL;
-
-	serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
-	if(serType == NULL){
-		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
-		return CELIX_SERVICE_EXCEPTION;
-	}
-
-	celixThreadMutex_lock(&admin->serializerListLock);
-	/* Remove the serializer from the list */
-	arrayList_removeElement(admin->serializerList, reference);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-	celixThreadMutex_lock(&admin->usedSerializersLock);
-	array_list_pt topicPubList = (array_list_pt)hashMap_remove(admin->topicPublicationsPerSerializer, service);
-	array_list_pt topicSubList = (array_list_pt)hashMap_remove(admin->topicSubscriptionsPerSerializer, service);
-	celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-	/* Now destroy the topicPublications, but first put back the pubsub_endpoints back to the noSerializer pending list */
-	if(topicPubList!=NULL){
-		for(i=0;i<arrayList_size(topicPubList);i++){
-			topic_publication_pt topicPub = (topic_publication_pt)arrayList_get(topicPubList,i);
-			/* Stop the topic publication */
-			pubsub_topicPublicationStop(topicPub);
-			/* Get the endpoints that are going to be orphan */
-			array_list_pt pubList = pubsub_topicPublicationGetPublisherList(topicPub);
-			for(j=0;j<arrayList_size(pubList);j++){
-				pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubList,j);
-				/* Remove the publication */
-				pubsubAdmin_removePublication(admin, pubEP);
-				/* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
-				if(pubEP->endpoint!=NULL){
-					free(pubEP->endpoint);
-					pubEP->endpoint = NULL;
-				}
-				/* Add the orphan endpoint to the noSerializer pending list */
-				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-				arrayList_add(admin->noSerializerPublications,pubEP);
-				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-			}
-			arrayList_destroy(pubList);
-
-			/* Cleanup also the localPublications hashmap*/
-			celixThreadMutex_lock(&admin->localPublicationsLock);
-			hash_map_iterator_pt iter = hashMapIterator_create(admin->localPublications);
-			char *key = NULL;
-			service_factory_pt factory = NULL;
-			while(hashMapIterator_hasNext(iter)){
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-				factory = (service_factory_pt)hashMapEntry_getValue(entry);
-				topic_publication_pt pub = (topic_publication_pt)factory->handle;
-				if(pub==topicPub){
-					key = (char*)hashMapEntry_getKey(entry);
-					break;
-				}
-			}
-			hashMapIterator_destroy(iter);
-			if(key!=NULL){
-				hashMap_remove(admin->localPublications, key);
-				free(factory);
-				free(key);
-			}
-			celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-			/* Finally destroy the topicPublication */
-			pubsub_topicPublicationDestroy(topicPub);
-		}
-		arrayList_destroy(topicPubList);
-	}
-
-	/* Now destroy the topicSubscriptions, but first put back the pubsub_endpoints back to the noSerializer pending list */
-	if(topicSubList!=NULL){
-		for(i=0;i<arrayList_size(topicSubList);i++){
-			topic_subscription_pt topicSub = (topic_subscription_pt)arrayList_get(topicSubList,i);
-			/* Stop the topic subscription */
-			pubsub_topicSubscriptionStop(topicSub);
-			/* Get the endpoints that are going to be orphan */
-			array_list_pt subList = pubsub_topicSubscriptionGetSubscribersList(topicSub);
-			for(j=0;j<arrayList_size(subList);j++){
-				pubsub_endpoint_pt subEP = (pubsub_endpoint_pt)arrayList_get(subList,j);
-				/* Remove the subscription */
-				pubsubAdmin_removeSubscription(admin, subEP);
-				/* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
-				if(subEP->endpoint!=NULL){
-					free(subEP->endpoint);
-					subEP->endpoint = NULL;
-				}
-				/* Add the orphan endpoint to the noSerializer pending list */
-				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-				arrayList_add(admin->noSerializerSubscriptions,subEP);
-				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-			}
-
-			/* Cleanup also the subscriptions hashmap*/
-			celixThreadMutex_lock(&admin->subscriptionsLock);
-			hash_map_iterator_pt iter = hashMapIterator_create(admin->subscriptions);
-			char *key = NULL;
-			while(hashMapIterator_hasNext(iter)){
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-				topic_subscription_pt sub = (topic_subscription_pt)hashMapEntry_getValue(entry);
-				if(sub==topicSub){
-					key = (char*)hashMapEntry_getKey(entry);
-					break;
-				}
-			}
-			hashMapIterator_destroy(iter);
-			if(key!=NULL){
-				hashMap_remove(admin->subscriptions, key);
-				free(key);
-			}
-			celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-			/* Finally destroy the topicSubscription */
-			pubsub_topicSubscriptionDestroy(topicSub);
-		}
-		arrayList_destroy(topicSubList);
-	}
-
-	printf("PSA_UDP_MC: %s serializer removed\n",serType);
-
-
-	return CELIX_SUCCESS;
-}
-
-celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&admin->serializerListLock);
-	status = pubsub_admin_match(endpoint->topic_props,PUBSUB_ADMIN_TYPE,admin->serializerList,score);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-	return status;
-}
-
-/* This one recall the same logic as in the match function */
-static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc){
-
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&admin->serializerListLock);
-	status = pubsub_admin_get_best_serializer(ep->topic_props, admin->serializerList, serSvc);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-	return status;
-
-}
-
-static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication){
-
-	celixThreadMutex_lock(&admin->usedSerializersLock);
-
-	hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
-	array_list_pt list = (array_list_pt)hashMap_get(map,serializer);
-	if(list==NULL){
-		arrayList_create(&list);
-		hashMap_put(map,serializer,list);
-	}
-	arrayList_add(list,topicPubSub);
-
-	celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-}
-
-static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication){
-
-	celixThreadMutex_lock(&admin->usedSerializersLock);
-
-	hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
-	hash_map_iterator_pt iter = hashMapIterator_create(map);
-	while(hashMapIterator_hasNext(iter)){
-		array_list_pt list = (array_list_pt)hashMapIterator_nextValue(iter);
-		if(arrayList_removeElement(list, topicPubSub)){ //Found it!
-			break;
-		}
-	}
-	hashMapIterator_destroy(iter);
-
-	celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c b/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
deleted file mode 100644
index e43ec29..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  htPSA_UDP_MC_TP://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * topic_publication.c
- *
- *  \date       Sep 24, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "array_list.h"
-#include "celixbool.h"
-#include "service_registration.h"
-#include "utils.h"
-#include "service_factory.h"
-#include "version.h"
-
-#include "topic_publication.h"
-#include "pubsub_common.h"
-#include "publisher.h"
-#include "large_udp.h"
-
-#include "pubsub_serializer.h"
-
-#define EP_ADDRESS_LEN		32
-
-#define FIRST_SEND_DELAY	2
-
-struct topic_publication {
-	int sendSocket;
-	char* endpoint;
-	service_registration_pt svcFactoryReg;
-	array_list_pt pub_ep_list; //List<pubsub_endpoint>
-	hash_map_pt boundServices; //<bundle_pt,bound_service>
-	celix_thread_mutex_t tp_lock;
-	pubsub_serializer_service_t *serializer;
-	struct sockaddr_in destAddr;
-};
-
-typedef struct publish_bundle_bound_service {
-	topic_publication_pt parent;
-	pubsub_publisher_t service;
-	bundle_pt bundle;
-	char *scope;
-	char *topic;
-	hash_map_pt msgTypes;
-	unsigned short getCount;
-	celix_thread_mutex_t mp_lock;
-	largeUdp_pt largeUdpHandle;
-}* publish_bundle_bound_service_pt;
-
-
-typedef struct pubsub_msg{
-	pubsub_msg_header_pt header;
-	char* payload;
-	unsigned int payloadSize;
-} pubsub_msg_t;
-
-
-static unsigned int rand_range(unsigned int min, unsigned int max);
-
-static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
-static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
-
-static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle);
-static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc);
-
-static int pubsub_topicPublicationSend(void* handle,unsigned int msgTypeId, const void *msg);
-
-static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId);
-
-
-static void delay_first_send_for_late_joiners(void);
-
-
-celix_status_t pubsub_topicPublicationCreate(int sendSocket, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, topic_publication_pt *out){
-
-	char* ep = malloc(EP_ADDRESS_LEN);
-	memset(ep,0,EP_ADDRESS_LEN);
-	unsigned int port = pubEP->serviceID + rand_range(UDP_BASE_PORT+pubEP->serviceID+3, UDP_MAX_PORT);
-	snprintf(ep,EP_ADDRESS_LEN,"udp://%s:%u",bindIP,port);
-
-
-	topic_publication_pt pub = calloc(1,sizeof(*pub));
-
-	arrayList_create(&(pub->pub_ep_list));
-	pub->boundServices = hashMap_create(NULL,NULL,NULL,NULL);
-	celixThreadMutex_create(&(pub->tp_lock),NULL);
-
-	pub->endpoint = ep;
-	pub->sendSocket = sendSocket;
-	pub->destAddr.sin_family = AF_INET;
-	pub->destAddr.sin_addr.s_addr = inet_addr(bindIP);
-	pub->destAddr.sin_port = htons(port);
-
-	pub->serializer = best_serializer;
-
-	pubsub_topicPublicationAddPublisherEP(pub,pubEP);
-
-	*out = pub;
-
-	return CELIX_SUCCESS;
-}
-
-celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&(pub->tp_lock));
-
-	free(pub->endpoint);
-	arrayList_destroy(pub->pub_ep_list);
-
-	hash_map_iterator_pt iter = hashMapIterator_create(pub->boundServices);
-	while(hashMapIterator_hasNext(iter)){
-		publish_bundle_bound_service_pt bound = hashMapIterator_nextValue(iter);
-		pubsub_destroyPublishBundleBoundService(bound);
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(pub->boundServices,false,false);
-
-	pub->svcFactoryReg = NULL;
-	pub->serializer = NULL;
-
-	if(close(pub->sendSocket) != 0){
-		status = CELIX_FILE_IO_EXCEPTION;
-	}
-
-	celixThreadMutex_unlock(&(pub->tp_lock));
-
-	celixThreadMutex_destroy(&(pub->tp_lock));
-
-	free(pub);
-
-	return status;
-}
-
-celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory){
-	celix_status_t status = CELIX_SUCCESS;
-
-	/* Let's register the new service */
-
-	pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pub->pub_ep_list,0);
-
-	if(pubEP!=NULL){
-		service_factory_pt factory = calloc(1, sizeof(*factory));
-		factory->handle = pub;
-		factory->getService = pubsub_topicPublicationGetService;
-		factory->ungetService = pubsub_topicPublicationUngetService;
-
-		properties_pt props = properties_create();
-		properties_set(props,PUBSUB_PUBLISHER_SCOPE,pubEP->scope);
-		properties_set(props,PUBSUB_PUBLISHER_TOPIC,pubEP->topic);
-
-		status = bundleContext_registerServiceFactory(bundle_context,PUBSUB_PUBLISHER_SERVICE_NAME,factory,props,&(pub->svcFactoryReg));
-
-		if(status != CELIX_SUCCESS){
-			properties_destroy(props);
-			printf("PSA_UDP_MC_PSA_UDP_MC_TP: Cannot register ServiceFactory for topic %s, topic %s (bundle %ld).\n",pubEP->scope, pubEP->topic,pubEP->serviceID);
-		}
-		else{
-			*svcFactory = factory;
-		}
-	}
-	else{
-		printf("PSA_UDP_MC_PSA_UDP_MC_TP: Cannot find pubsub_endpoint after adding it...Should never happen!\n");
-		status = CELIX_SERVICE_EXCEPTION;
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub){
-	return serviceRegistration_unregister(pub->svcFactoryReg);
-}
-
-celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
-
-	celixThreadMutex_lock(&(pub->tp_lock));
-	ep->endpoint = strdup(pub->endpoint);
-	arrayList_add(pub->pub_ep_list,ep);
-	celixThreadMutex_unlock(&(pub->tp_lock));
-
-	return CELIX_SUCCESS;
-}
-
-celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
-
-	celixThreadMutex_lock(&(pub->tp_lock));
-	arrayList_removeElement(pub->pub_ep_list,ep);
-	celixThreadMutex_unlock(&(pub->tp_lock));
-
-	return CELIX_SUCCESS;
-}
-
-array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub){
-	array_list_pt list = NULL;
-	celixThreadMutex_lock(&(pub->tp_lock));
-	list = arrayList_clone(pub->pub_ep_list);
-	celixThreadMutex_unlock(&(pub->tp_lock));
-	return list;
-}
-
-
-static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service) {
-	celix_status_t  status = CELIX_SUCCESS;
-
-	topic_publication_pt publish = (topic_publication_pt)handle;
-
-	celixThreadMutex_lock(&(publish->tp_lock));
-
-	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
-	if(bound==NULL){
-		bound = pubsub_createPublishBundleBoundService(publish,bundle);
-		if(bound!=NULL){
-			hashMap_put(publish->boundServices,bundle,bound);
-		}
-	}
-	else{
-		bound->getCount++;
-	}
-
-	if (bound != NULL) {
-		*service = &bound->service;
-	}
-
-	celixThreadMutex_unlock(&(publish->tp_lock));
-
-	return status;
-}
-
-static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service)  {
-
-	topic_publication_pt publish = (topic_publication_pt)handle;
-
-	celixThreadMutex_lock(&(publish->tp_lock));
-
-	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
-	if(bound!=NULL){
-
-		bound->getCount--;
-		if(bound->getCount==0){
-			pubsub_destroyPublishBundleBoundService(bound);
-			hashMap_remove(publish->boundServices,bundle);
-		}
-
-	}
-	else{
-		long bundleId = -1;
-		bundle_getBundleId(bundle,&bundleId);
-		printf("PSA_UDP_MC_TP: Unexpected ungetService call for bundle %ld.\n", bundleId);
-	}
-
-	/* service should be never used for unget, so let's set the pointer to NULL */
-	*service = NULL;
-
-	celixThreadMutex_unlock(&(publish->tp_lock));
-
-	return CELIX_SUCCESS;
-}
-
-static bool send_pubsub_msg(publish_bundle_bound_service_pt bound, pubsub_msg_t* msg, bool last, pubsub_release_callback_t *releaseCallback){
-	const int iovec_len = 3; // header + size + payload
-	bool ret = true;
-
-	struct iovec msg_iovec[iovec_len];
-	msg_iovec[0].iov_base = msg->header;
-	msg_iovec[0].iov_len = sizeof(*msg->header);
-	msg_iovec[1].iov_base = &msg->payloadSize;
-	msg_iovec[1].iov_len = sizeof(msg->payloadSize);
-	msg_iovec[2].iov_base = msg->payload;
-	msg_iovec[2].iov_len = msg->payloadSize;
-
-	delay_first_send_for_late_joiners();
-
-	if(largeUdp_sendmsg(bound->largeUdpHandle, bound->parent->sendSocket, msg_iovec, iovec_len, 0, &bound->parent->destAddr, sizeof(bound->parent->destAddr)) == -1) {
-		perror("send_pubsub_msg:sendSocket");
-		ret = false;
-	}
-
-	if(releaseCallback) {
-		releaseCallback->release(msg->payload, bound);
-	}
-	return ret;
-
-}
-
-
-static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *inMsg) {
-	int status = 0;
-	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt) handle;
-
-	celixThreadMutex_lock(&(bound->parent->tp_lock));
-	celixThreadMutex_lock(&(bound->mp_lock));
-
-	pubsub_msg_serializer_t* msgSer = (pubsub_msg_serializer_t*)hashMap_get(bound->msgTypes, (void*)(uintptr_t)msgTypeId);
-
-	if (msgSer != NULL) {
-		int major=0, minor=0;
-
-		pubsub_msg_header_pt msg_hdr = calloc(1,sizeof(struct pubsub_msg_header));
-		strncpy(msg_hdr->topic,bound->topic,MAX_TOPIC_LEN-1);
-		msg_hdr->type = msgTypeId;
-
-
-		if (msgSer->msgVersion != NULL){
-			version_getMajor(msgSer->msgVersion, &major);
-			version_getMinor(msgSer->msgVersion, &minor);
-			msg_hdr->major = major;
-			msg_hdr->minor = minor;
-		}
-
-		void* serializedOutput = NULL;
-		size_t serializedOutputLen = 0;
-		msgSer->serialize(msgSer,inMsg,&serializedOutput, &serializedOutputLen);
-
-		pubsub_msg_t *msg = calloc(1,sizeof(pubsub_msg_t));
-		msg->header = msg_hdr;
-		msg->payload = (char*)serializedOutput;
-		msg->payloadSize = serializedOutputLen;
-
-
-		if(send_pubsub_msg(bound, msg,true, NULL) == false) {
-			status = -1;
-		}
-		free(msg_hdr);
-		free(msg);
-		free(serializedOutput);
-
-
-	} else {
-		printf("PSA_UDP_MC_TP: No msg serializer available for msg type id %d\n", msgTypeId);
-		status=-1;
-	}
-
-	celixThreadMutex_unlock(&(bound->mp_lock));
-	celixThreadMutex_unlock(&(bound->parent->tp_lock));
-
-	return status;
-}
-
-static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId){
-	*msgTypeId = utils_stringHash(msgType);
-	return 0;
-}
-
-
-static unsigned int rand_range(unsigned int min, unsigned int max){
-
-	double scaled = (double)(((double)random())/((double)RAND_MAX));
-	return (max-min+1)*scaled + min;
-
-}
-
-static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle){
-
-	publish_bundle_bound_service_pt bound = calloc(1, sizeof(*bound));
-
-	if (bound != NULL) {
-
-		bound->parent = tp;
-		bound->bundle = bundle;
-		bound->getCount = 1;
-		celixThreadMutex_create(&bound->mp_lock,NULL);
-
-		if(tp->serializer != NULL){
-			tp->serializer->createSerializerMap(tp->serializer->handle,bundle,&bound->msgTypes);
-		}
-
-		pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(bound->parent->pub_ep_list,0);
-		bound->scope=strdup(pubEP->scope);
-		bound->topic=strdup(pubEP->topic);
-		bound->largeUdpHandle = largeUdp_create(1);
-
-		bound->service.handle = bound;
-		bound->service.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForUUID;
-		bound->service.send = pubsub_topicPublicationSend;
-		bound->service.sendMultipart = NULL;  //Multipart not supported for UDP
-
-	}
-
-	return bound;
-}
-
-static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc){
-
-	celixThreadMutex_lock(&boundSvc->mp_lock);
-
-	if(boundSvc->parent->serializer != NULL && boundSvc->msgTypes != NULL){
-		boundSvc->parent->serializer->destroySerializerMap(boundSvc->parent->serializer->handle, boundSvc->msgTypes);
-	}
-
-	if(boundSvc->scope!=NULL){
-		free(boundSvc->scope);
-	}
-
-	if(boundSvc->topic!=NULL){
-		free(boundSvc->topic);
-	}
-
-	largeUdp_destroy(boundSvc->largeUdpHandle);
-
-	celixThreadMutex_unlock(&boundSvc->mp_lock);
-	celixThreadMutex_destroy(&boundSvc->mp_lock);
-
-	free(boundSvc);
-
-}
-
-static void delay_first_send_for_late_joiners(){
-
-	static bool firstSend = true;
-
-	if(firstSend){
-		printf("PSA_UDP_MC_TP: Delaying first send for late joiners...\n");
-		sleep(FIRST_SEND_DELAY);
-		firstSend = false;
-	}
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/topic_subscription.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/topic_subscription.c b/pubsub/pubsub_admin_udp_mc/private/src/topic_subscription.c
deleted file mode 100644
index d8e6f45..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/topic_subscription.c
+++ /dev/null
@@ -1,635 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * topic_subscription.c
- *
- *  \date       Oct 2, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/epoll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "utils.h"
-#include "celix_errno.h"
-#include "constants.h"
-#include "version.h"
-
-#include "topic_subscription.h"
-#include "topic_publication.h"
-#include "subscriber.h"
-#include "publisher.h"
-#include "large_udp.h"
-
-#include "pubsub_serializer.h"
-
-#define MAX_EPOLL_EVENTS        10
-#define RECV_THREAD_TIMEOUT     5
-#define UDP_BUFFER_SIZE         65535
-#define MAX_UDP_SESSIONS        16
-
-struct topic_subscription{
-	char* ifIpAddress;
-	service_tracker_pt tracker;
-	array_list_pt sub_ep_list;
-	celix_thread_t recv_thread;
-	bool running;
-	celix_thread_mutex_t ts_lock;
-	bundle_context_pt context;
-
-	pubsub_serializer_service_t *serializer;
-
-	int topicEpollFd; // EPOLL filedescriptor where the sockets are registered.
-	hash_map_pt servicesMap; // key = service, value = msg types map
-	hash_map_pt socketMap; // key = URL, value = listen-socket
-	celix_thread_mutex_t socketMap_lock;
-
-	celix_thread_mutex_t pendingConnections_lock;
-	array_list_pt pendingConnections;
-
-	array_list_pt pendingDisconnections;
-	celix_thread_mutex_t pendingDisconnections_lock;
-
-	//array_list_pt rawServices;
-	unsigned int nrSubscribers;
-	largeUdp_pt largeUdpHandle;
-};
-
-typedef struct msg_map_entry{
-	bool retain;
-	void* msgInst;
-}* msg_map_entry_pt;
-
-static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service);
-static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service);
-static void* udp_recv_thread_func(void* arg);
-static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr);
-static void sigusr1_sighandler(int signo);
-static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId);
-static void connectPendingPublishers(topic_subscription_pt sub);
-static void disconnectPendingPublishers(topic_subscription_pt sub);
-
-
-celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* ifIp,char* scope, char* topic ,pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out){
-	celix_status_t status = CELIX_SUCCESS;
-
-	topic_subscription_pt ts = (topic_subscription_pt) calloc(1,sizeof(*ts));
-	ts->context = bundle_context;
-	ts->ifIpAddress = strdup(ifIp);
-#if defined(__APPLE__) && defined(__MACH__)
-	//TODO: Use kqueue for OSX
-#else
-	ts->topicEpollFd = epoll_create1(0);
-#endif
-	if(ts->topicEpollFd == -1) {
-		status += CELIX_SERVICE_EXCEPTION;
-	}
-
-	ts->running = false;
-	ts->nrSubscribers = 0;
-	ts->serializer = best_serializer;
-
-	celixThreadMutex_create(&ts->ts_lock,NULL);
-	arrayList_create(&ts->sub_ep_list);
-	ts->servicesMap = hashMap_create(NULL, NULL, NULL, NULL);
-	ts->socketMap =  hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-	arrayList_create(&ts->pendingConnections);
-	arrayList_create(&ts->pendingDisconnections);
-	celixThreadMutex_create(&ts->pendingConnections_lock, NULL);
-	celixThreadMutex_create(&ts->pendingDisconnections_lock, NULL);
-	celixThreadMutex_create(&ts->socketMap_lock, NULL);
-
-	ts->largeUdpHandle = largeUdp_create(MAX_UDP_SESSIONS);
-
-	char filter[128];
-	memset(filter,0,128);
-	if(strncmp(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, scope, strlen(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT)) == 0) {
-		// default scope, means that subscriber has not defined a scope property
-		snprintf(filter, 128, "(&(%s=%s)(%s=%s))",
-				(char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
-				PUBSUB_SUBSCRIBER_TOPIC,topic);
-
-	} else {
-		snprintf(filter, 128, "(&(%s=%s)(%s=%s)(%s=%s))",
-				(char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
-				PUBSUB_SUBSCRIBER_TOPIC,topic,
-				PUBSUB_SUBSCRIBER_SCOPE,scope);
-	}
-
-	service_tracker_customizer_pt customizer = NULL;
-	status += serviceTrackerCustomizer_create(ts,NULL,topicsub_subscriberTracked,NULL,topicsub_subscriberUntracked,&customizer);
-	status += serviceTracker_createWithFilter(bundle_context, filter, customizer, &ts->tracker);
-
-	struct sigaction actions;
-	memset(&actions, 0, sizeof(actions));
-	sigemptyset(&actions.sa_mask);
-	actions.sa_flags = 0;
-	actions.sa_handler = sigusr1_sighandler;
-
-	sigaction(SIGUSR1,&actions,NULL);
-
-	if (status == CELIX_SUCCESS) {
-		*out=ts;
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	ts->running = false;
-	free(ts->ifIpAddress);
-	serviceTracker_destroy(ts->tracker);
-	arrayList_clear(ts->sub_ep_list);
-	arrayList_destroy(ts->sub_ep_list);
-	hashMap_destroy(ts->servicesMap,false,false);
-
-	celixThreadMutex_lock(&ts->socketMap_lock);
-	hashMap_destroy(ts->socketMap,true,true);
-	celixThreadMutex_unlock(&ts->socketMap_lock);
-	celixThreadMutex_destroy(&ts->socketMap_lock);
-
-	celixThreadMutex_lock(&ts->pendingConnections_lock);
-	arrayList_destroy(ts->pendingConnections);
-	celixThreadMutex_unlock(&ts->pendingConnections_lock);
-	celixThreadMutex_destroy(&ts->pendingConnections_lock);
-
-	celixThreadMutex_lock(&ts->pendingDisconnections_lock);
-	arrayList_destroy(ts->pendingDisconnections);
-	celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
-	celixThreadMutex_destroy(&ts->pendingDisconnections_lock);
-
-	largeUdp_destroy(ts->largeUdpHandle);
-#if defined(__APPLE__) && defined(__MACH__)
-	//TODO: Use kqueue for OSX
-#else
-	close(ts->topicEpollFd);
-#endif
-
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	celixThreadMutex_destroy(&ts->ts_lock);
-
-	free(ts);
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts){
-	celix_status_t status = CELIX_SUCCESS;
-
-	status = serviceTracker_open(ts->tracker);
-
-	ts->running = true;
-
-	if(status==CELIX_SUCCESS){
-		status=celixThread_create(&ts->recv_thread,NULL,udp_recv_thread_func,ts);
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts){
-	celix_status_t status = CELIX_SUCCESS;
-	struct epoll_event ev;
-	memset(&ev, 0, sizeof(ev));
-
-	ts->running = false;
-
-	pthread_kill(ts->recv_thread.thread,SIGUSR1);
-
-	celixThread_join(ts->recv_thread,NULL);
-
-	status = serviceTracker_close(ts->tracker);
-
-	celixThreadMutex_lock(&ts->socketMap_lock);
-	hash_map_iterator_pt it = hashMapIterator_create(ts->socketMap);
-	while(hashMapIterator_hasNext(it)) {
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(it);
-		char *url = hashMapEntry_getKey(entry);
-		int *s = hashMapEntry_getValue(entry);
-		memset(&ev, 0, sizeof(ev));
-		if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_DEL, *s, &ev) == -1) {
-			printf("in if error()\n");
-			perror("epoll_ctl() EPOLL_CTL_DEL");
-			status += CELIX_SERVICE_EXCEPTION;
-		}
-		free(s);
-		free(url);
-		//hashMapIterator_remove(it);
-	}
-	hashMapIterator_destroy(it);
-	hashMap_clear(ts->socketMap, false, false);
-	celixThreadMutex_unlock(&ts->socketMap_lock);
-
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL) {
-
-	printf("pubsub_topicSubscriptionConnectPublisher : pubURL = %s\n", pubURL);
-
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->socketMap_lock);
-
-	if(!hashMap_containsKey(ts->socketMap, pubURL)){
-
-		int *recvSocket = calloc(sizeof(int), 1);
-		*recvSocket = socket(AF_INET, SOCK_DGRAM, 0);
-		if (*recvSocket < 0) {
-			perror("pubsub_topicSubscriptionCreate:socket");
-			status = CELIX_SERVICE_EXCEPTION;
-		}
-
-		if (status == CELIX_SUCCESS){
-			int reuse = 1;
-			if (setsockopt(*recvSocket, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) != 0) {
-				perror("setsockopt() SO_REUSEADDR");
-				status = CELIX_SERVICE_EXCEPTION;
-			}
-		}
-
-		if(status == CELIX_SUCCESS){
-			// TODO Check if there is a better way to parse the URL to IP/Portnr
-			//replace ':' by spaces
-			char *url = strdup(pubURL);
-			char *pt = url;
-			while((pt=strchr(pt, ':')) != NULL) {
-				*pt = ' ';
-			}
-			char mcIp[100];
-			unsigned short mcPort;
-			sscanf(url, "udp //%s %hu", mcIp, &mcPort);
-			free(url);
-
-			printf("pubsub_topicSubscriptionConnectPublisher : IP = %s, Port = %hu\n", mcIp, mcPort);
-
-			struct ip_mreq mc_addr;
-			mc_addr.imr_multiaddr.s_addr = inet_addr(mcIp);
-			mc_addr.imr_interface.s_addr = inet_addr(ts->ifIpAddress);
-			printf("Adding MC %s at interface %s\n", mcIp, ts->ifIpAddress);
-			if (setsockopt(*recvSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mc_addr, sizeof(mc_addr)) != 0) {
-				perror("setsockopt() IP_ADD_MEMBERSHIP");
-				status = CELIX_SERVICE_EXCEPTION;
-			}
-
-			if (status == CELIX_SUCCESS){
-				struct sockaddr_in mcListenAddr;
-				mcListenAddr.sin_family = AF_INET;
-				mcListenAddr.sin_addr.s_addr = INADDR_ANY;
-				mcListenAddr.sin_port = htons(mcPort);
-				if(bind(*recvSocket, (struct sockaddr*)&mcListenAddr, sizeof(mcListenAddr)) != 0) {
-					perror("bind()");
-					status = CELIX_SERVICE_EXCEPTION;
-				}
-			}
-
-			if (status == CELIX_SUCCESS){
-#if defined(__APPLE__) && defined(__MACH__)
-				//TODO: Use kqueue for OSX
-#else
-				struct epoll_event ev;
-				memset(&ev, 0, sizeof(ev));
-				ev.events = EPOLLIN;
-				ev.data.fd = *recvSocket;
-				if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_ADD, *recvSocket, &ev) == -1) {
-					perror("epoll_ctl() EPOLL_CTL_ADD");
-					status = CELIX_SERVICE_EXCEPTION;
-				}
-#endif
-			}
-
-		}
-
-		if (status == CELIX_SUCCESS){
-			hashMap_put(ts->socketMap, strdup(pubURL), (void*)recvSocket);
-		}
-		else{
-			free(recvSocket);
-		}
-	}
-
-	celixThreadMutex_unlock(&ts->socketMap_lock);
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
-	celix_status_t status = CELIX_SUCCESS;
-	char *url = strdup(pubURL);
-	celixThreadMutex_lock(&ts->pendingConnections_lock);
-	arrayList_add(ts->pendingConnections, url);
-	celixThreadMutex_unlock(&ts->pendingConnections_lock);
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
-	celix_status_t status = CELIX_SUCCESS;
-	char *url = strdup(pubURL);
-	celixThreadMutex_lock(&ts->pendingDisconnections_lock);
-	arrayList_add(ts->pendingDisconnections, url);
-	celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL){
-	printf("pubsub_topicSubscriptionDisconnectPublisher : pubURL = %s\n", pubURL);
-	celix_status_t status = CELIX_SUCCESS;
-	struct epoll_event ev;
-	memset(&ev, 0, sizeof(ev));
-
-	celixThreadMutex_lock(&ts->socketMap_lock);
-
-	if (hashMap_containsKey(ts->socketMap, pubURL)){
-
-#if defined(__APPLE__) && defined(__MACH__)
-		//TODO: Use kqueue for OSX
-#else
-		int *s = hashMap_remove(ts->socketMap, pubURL);
-		if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_DEL, *s, &ev) == -1) {
-			printf("in if error()\n");
-			perror("epoll_ctl() EPOLL_CTL_DEL");
-			status = CELIX_SERVICE_EXCEPTION;
-		}
-		free(s);
-#endif
-
-	}
-
-	celixThreadMutex_unlock(&ts->socketMap_lock);
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	arrayList_add(ts->sub_ep_list,subEP);
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-
-}
-
-celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt ts) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	ts->nrSubscribers++;
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	arrayList_removeElement(ts->sub_ep_list,subEP);
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-}
-
-celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt ts) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	ts->nrSubscribers--;
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-}
-
-unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt ts) {
-	return ts->nrSubscribers;
-}
-
-array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub){
-	return sub->sub_ep_list;
-}
-
-
-static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service){
-	celix_status_t status = CELIX_SUCCESS;
-	topic_subscription_pt ts = handle;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	if (!hashMap_containsKey(ts->servicesMap, service)) {
-		bundle_pt bundle = NULL;
-		hash_map_pt msgTypes = NULL;
-
-		serviceReference_getBundle(reference, &bundle);
-
-		if(ts->serializer != NULL && bundle!=NULL){
-			ts->serializer->createSerializerMap(ts->serializer->handle,bundle,&msgTypes);
-			if(msgTypes != NULL){
-				hashMap_put(ts->servicesMap, service, msgTypes);
-				printf("PSA_UDP_MC_TS: New subscriber registered.\n");
-			}
-		}
-		else{
-			printf("PSA_UDP_MC_TS: Cannot register new subscriber.\n");
-			status = CELIX_SERVICE_EXCEPTION;
-		}
-	}
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-
-}
-
-static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service){
-	celix_status_t status = CELIX_SUCCESS;
-	topic_subscription_pt ts = handle;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	if (hashMap_containsKey(ts->servicesMap, service)) {
-		hash_map_pt msgTypes = hashMap_remove(ts->servicesMap, service);
-		if(msgTypes!=NULL && ts->serializer!=NULL){
-			ts->serializer->destroySerializerMap(ts->serializer->handle,msgTypes);
-			printf("PSA_ZMQ_TS: Subscriber unregistered.\n");
-		}
-		else{
-			printf("PSA_ZMQ_TS: Cannot unregister subscriber.\n");
-			status = CELIX_SERVICE_EXCEPTION;
-		}
-	}
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	printf("PSA_UDP_MC_TS: Subscriber unregistered.\n");
-	return status;
-}
-
-
-static void process_msg(topic_subscription_pt sub,pubsub_udp_msg_t *msg){
-
-	celixThreadMutex_lock(&sub->ts_lock);
-	hash_map_iterator_pt iter = hashMapIterator_create(sub->servicesMap);
-	while (hashMapIterator_hasNext(iter)) {
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-		pubsub_subscriber_pt subsvc = hashMapEntry_getKey(entry);
-		hash_map_pt msgTypes = hashMapEntry_getValue(entry);
-
-		pubsub_msg_serializer_t *msgSer = hashMap_get(msgTypes,(void*)(uintptr_t )msg->header.type);
-		if (msgSer == NULL) {
-			printf("PSA_UDP_MC_TS: Serializer not available for message %d.\n",msg->header.type);
-		}
-		else{
-			void *msgInst = NULL;
-			bool validVersion = checkVersion(msgSer->msgVersion,&msg->header);
-
-			if(validVersion){
-
-				celix_status_t status = msgSer->deserialize(msgSer, (const void *) msg->payload, 0, &msgInst);
-
-				if (status == CELIX_SUCCESS) {
-					bool release = true;
-					pubsub_multipart_callbacks_t mp_callbacks;
-					mp_callbacks.handle = sub;
-					mp_callbacks.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForMsgType;
-					mp_callbacks.getMultipart = NULL;
-
-					subsvc->receive(subsvc->handle, msgSer->msgName, msg->header.type, msgInst, &mp_callbacks, &release);
-
-					if(release){
-						msgSer->freeMsg(msgSer,msgInst);
-					}
-				}
-				else{
-					printf("PSA_UDP_MC_TS: Cannot deserialize msgType %s.\n",msgSer->msgName);
-				}
-
-			}
-			else{
-				int major=0,minor=0;
-				version_getMajor(msgSer->msgVersion,&major);
-				version_getMinor(msgSer->msgVersion,&minor);
-				printf("PSA_UDP_MC_TS: Version mismatch for primary message '%s' (have %d.%d, received %u.%u). NOT sending any part of the whole message.\n",
-						msgSer->msgName,major,minor,msg->header.major,msg->header.minor);
-			}
-
-		}
-	}
-	hashMapIterator_destroy(iter);
-	celixThreadMutex_unlock(&sub->ts_lock);
-}
-
-static void* udp_recv_thread_func(void * arg) {
-	topic_subscription_pt sub = (topic_subscription_pt) arg;
-
-#if defined(__APPLE__) && defined(__MACH__)
-	//TODO: use kqueue for OSX
-	//struct kevent events[MAX_EPOLL_EVENTS];
-	while (sub->running) {
-		int nfds = 0;
-		if(nfds > 0) {
-			pubsub_udp_msg_t* udpMsg = NULL;
-			process_msg(sub, udpMsg);
-		}
-	}
-#else
-	struct epoll_event events[MAX_EPOLL_EVENTS];
-
-	while (sub->running) {
-		int nfds = epoll_wait(sub->topicEpollFd, events, MAX_EPOLL_EVENTS, RECV_THREAD_TIMEOUT * 1000);
-		int i;
-		for(i = 0; i < nfds; i++ ) {
-			unsigned int index;
-			unsigned int size;
-			if(largeUdp_dataAvailable(sub->largeUdpHandle, events[i].data.fd, &index, &size) == true) {
-				// Handle data
-				pubsub_udp_msg_t *udpMsg = NULL;
-				if(largeUdp_read(sub->largeUdpHandle, index, (void**)&udpMsg, size) != 0) {
-					printf("PSA_UDP_MC_TS: ERROR largeUdp_read with index %d\n", index);
-					continue;
-				}
-
-				process_msg(sub, udpMsg);
-
-				free(udpMsg);
-			}
-		}
-		connectPendingPublishers(sub);
-		disconnectPendingPublishers(sub);
-	}
-#endif
-
-	return NULL;
-}
-
-static void connectPendingPublishers(topic_subscription_pt sub) {
-	celixThreadMutex_lock(&sub->pendingConnections_lock);
-	while(!arrayList_isEmpty(sub->pendingConnections)) {
-		char * pubEP = arrayList_remove(sub->pendingConnections, 0);
-		pubsub_topicSubscriptionConnectPublisher(sub, pubEP);
-		free(pubEP);
-	}
-	celixThreadMutex_unlock(&sub->pendingConnections_lock);
-}
-
-static void disconnectPendingPublishers(topic_subscription_pt sub) {
-	celixThreadMutex_lock(&sub->pendingDisconnections_lock);
-	while(!arrayList_isEmpty(sub->pendingDisconnections)) {
-		char * pubEP = arrayList_remove(sub->pendingDisconnections, 0);
-		pubsub_topicSubscriptionDisconnectPublisher(sub, pubEP);
-		free(pubEP);
-	}
-	celixThreadMutex_unlock(&sub->pendingDisconnections_lock);
-}
-
-static void sigusr1_sighandler(int signo){
-	printf("PSA_UDP_MC_TS: Topic subscription being shut down...\n");
-	return;
-}
-
-static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr){
-	bool check=false;
-	int major=0,minor=0;
-
-	if(msgVersion!=NULL){
-		version_getMajor(msgVersion,&major);
-		version_getMinor(msgVersion,&minor);
-		if(hdr->major==((unsigned char)major)){ /* Different major means incompatible */
-			check = (hdr->minor>=((unsigned char)minor)); /* Compatible only if the provider has a minor equals or greater (means compatible update) */
-		}
-	}
-
-	return check;
-}
-
-static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId){
-	*msgTypeId = utils_stringHash(msgType);
-	return 0;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/large_udp.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/large_udp.c b/pubsub/pubsub_admin_udp_mc/src/large_udp.c
new file mode 100644
index 0000000..7455925
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/large_udp.c
@@ -0,0 +1,372 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * large_udp.c
+ *
+ *  \date       Mar 1, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include "large_udp.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <array_list.h>
+#include <pthread.h>
+
+#define MAX_UDP_MSG_SIZE 65535   /* 2^16 -1 */
+#define IP_HEADER_SIZE  20
+#define UDP_HEADER_SIZE 8
+//#define MTU_SIZE    1500
+#define MTU_SIZE    8000
+#define MAX_MSG_VECTOR_LEN 64
+
+//#define NO_IP_FRAGMENTATION
+
+struct largeUdp {
+	unsigned int maxNrLists;
+	array_list_pt udpPartLists;
+	pthread_mutex_t dbLock;
+};
+
+typedef struct udpPartList {
+	unsigned int msg_ident;
+	unsigned int msg_size;
+	unsigned int nrPartsRemaining;
+	char *data;
+} *udpPartList_pt;
+
+
+typedef struct msg_part_header {
+	unsigned int msg_ident;
+	unsigned int total_msg_size;
+	unsigned int part_msg_size;
+	unsigned int offset;
+} msg_part_header_t;
+
+#ifdef NO_IP_FRAGMENTATION
+#define MAX_PART_SIZE   (MTU_SIZE - (IP_HEADER_SIZE + UDP_HEADER_SIZE + sizeof(struct msg_part_header) ))
+#else
+#define MAX_PART_SIZE   (MAX_UDP_MSG_SIZE - (IP_HEADER_SIZE + UDP_HEADER_SIZE + sizeof(struct msg_part_header) ))
+#endif
+
+typedef struct msg_part {
+	msg_part_header_t header;
+	char data[MAX_PART_SIZE];
+} msg_part_t;
+
+//
+// Create a handle
+//
+largeUdp_pt largeUdp_create(unsigned int maxNrUdpReceptions)
+{
+	printf("## Creating large UDP\n");
+	largeUdp_pt handle = calloc(sizeof(*handle), 1);
+	if(handle != NULL) {
+		handle->maxNrLists = maxNrUdpReceptions;
+		if(arrayList_create(&handle->udpPartLists) != CELIX_SUCCESS) {
+			free(handle);
+			handle = NULL;
+		}
+		pthread_mutex_init(&handle->dbLock, 0);
+	}
+
+	return handle;
+}
+
+//
+// Destroys the handle
+//
+void largeUdp_destroy(largeUdp_pt handle)
+{
+	printf("### Destroying large UDP\n");
+	if(handle != NULL) {
+		pthread_mutex_lock(&handle->dbLock);
+		int nrUdpLists = arrayList_size(handle->udpPartLists);
+		int i;
+		for(i=0; i < nrUdpLists; i++) {
+			udpPartList_pt udpPartList = arrayList_remove(handle->udpPartLists, i);
+			if(udpPartList) {
+				if(udpPartList->data) {
+					free(udpPartList->data);
+					udpPartList->data = NULL;
+				}
+				free(udpPartList);
+			}
+		}
+		arrayList_destroy(handle->udpPartLists);
+		handle->udpPartLists = NULL;
+		pthread_mutex_unlock(&handle->dbLock);
+		pthread_mutex_destroy(&handle->dbLock);
+		free(handle);
+	}
+}
+
+//
+// Write large data to UDP. This function splits the data in chunks and sends these chunks with a header over UDP.
+//
+int largeUdp_sendmsg(largeUdp_pt handle, int fd, struct iovec *largeMsg_iovec, int len, int flags, struct sockaddr_in *dest_addr, size_t addrlen)
+{
+	int n;
+	int result = 0;
+	msg_part_header_t header;
+
+	int written = 0;
+	header.msg_ident = (unsigned int)random();
+	header.total_msg_size = 0;
+	for(n = 0; n < len ;n++) {
+		header.total_msg_size += largeMsg_iovec[n].iov_len;
+	}
+	int nr_buffers = (header.total_msg_size / MAX_PART_SIZE) + 1;
+
+	struct iovec msg_iovec[MAX_MSG_VECTOR_LEN];
+	struct msghdr msg;
+	msg.msg_name = dest_addr;
+	msg.msg_namelen = addrlen;
+	msg.msg_flags = 0;
+	msg.msg_iov = msg_iovec;
+	msg.msg_iovlen = 2; // header and payload;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+
+	msg.msg_iov[0].iov_base = &header;
+	msg.msg_iov[0].iov_len = sizeof(header);
+
+	for(n = 0; n < nr_buffers; n++) {
+
+		header.part_msg_size = (((header.total_msg_size - n * MAX_PART_SIZE) >  MAX_PART_SIZE) ?  MAX_PART_SIZE  : (header.total_msg_size - n * MAX_PART_SIZE));
+		header.offset = n * MAX_PART_SIZE;
+		int remainingOffset = header.offset;
+		int recvPart = 0;
+		// find the start of the part
+		while(remainingOffset > largeMsg_iovec[recvPart].iov_len) {
+			remainingOffset -= largeMsg_iovec[recvPart].iov_len;
+			recvPart++;
+		}
+		int remainingData = header.part_msg_size;
+		int sendPart = 1;
+		msg.msg_iovlen = 1;
+
+		// fill in the output iovec from the input iovec in such a way that all UDP frames are filled maximal.
+		while(remainingData > 0) {
+			int partLen = ( (largeMsg_iovec[recvPart].iov_len - remainingOffset) <= remainingData ? (largeMsg_iovec[recvPart].iov_len -remainingOffset) : remainingData);
+			msg.msg_iov[sendPart].iov_base = largeMsg_iovec[recvPart].iov_base + remainingOffset;
+			msg.msg_iov[sendPart].iov_len = partLen;
+			remainingData -= partLen;
+			remainingOffset = 0;
+			sendPart++;
+			recvPart++;
+			msg.msg_iovlen++;
+		}
+		int tmp, tmptot;
+		for(tmp = 0, tmptot=0; tmp < msg.msg_iovlen; tmp++) {
+			tmptot += msg.msg_iov[tmp].iov_len;
+		}
+
+		int w = sendmsg(fd, &msg, 0);
+		if(w == -1) {
+			perror("send()");
+			result =  -1;
+			break;
+		}
+		written += w;
+	}
+
+	return (result == 0 ? written : result);
+}
+
+//
+// Write large data to UDP. This function splits the data in chunks and sends these chunks with a header over UDP.
+//
+int largeUdp_sendto(largeUdp_pt handle, int fd, void *buf, size_t count, int flags, struct sockaddr_in *dest_addr, size_t addrlen)
+{
+	int n;
+	int nr_buffers = (count / MAX_PART_SIZE) + 1;
+	int result = 0;
+	msg_part_header_t header;
+
+	int written = 0;
+	header.msg_ident = (unsigned int)random();
+	header.total_msg_size = count;
+	char *databuf = buf;
+
+	struct iovec msg_iovec[2];
+	struct msghdr msg;
+	msg.msg_name = dest_addr;
+	msg.msg_namelen = addrlen;
+	msg.msg_flags = 0;
+	msg.msg_iov = msg_iovec;
+	msg.msg_iovlen = 2; // header and payload;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+
+	msg.msg_iov[0].iov_base = &header;
+	msg.msg_iov[0].iov_len = sizeof(header);
+
+	for(n = 0; n < nr_buffers; n++) {
+
+		header.part_msg_size = (((header.total_msg_size - n * MAX_PART_SIZE) >  MAX_PART_SIZE) ?  MAX_PART_SIZE  : (header.total_msg_size - n * MAX_PART_SIZE));
+		header.offset = n * MAX_PART_SIZE;
+		msg.msg_iov[1].iov_base = &databuf[header.offset];
+		msg.msg_iov[1].iov_len = header.part_msg_size;
+		int w = sendmsg(fd, &msg, 0);
+		if(w == -1) {
+			perror("send()");
+			result =  -1;
+			break;
+		}
+		written += w;
+		//usleep(1000); // TODO: If not slept a UDP buffer overflow occurs and parts are missing at the reception side (at least via localhost)
+	}
+
+	return (result == 0 ? written : result);
+}
+
+//
+// Reads data from the filedescriptor which has date (determined by epoll()) and stores it in the internal structure
+// If the message is completely reassembled true is returned and the index and size have valid values
+//
+bool largeUdp_dataAvailable(largeUdp_pt handle, int fd, unsigned int *index, unsigned int *size) {
+	msg_part_header_t header;
+	int result = false;
+	// Only read the header, we don't know yet where to store the payload
+	if(recv(fd, &header, sizeof(header), MSG_PEEK) < 0) {
+		perror("read()");
+		return false;
+	}
+
+	struct iovec msg_vec[2];
+	struct msghdr msg;
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_flags = 0;
+	msg.msg_iov = msg_vec;
+	msg.msg_iovlen = 2; // header and payload;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+
+	msg.msg_iov[0].iov_base = &header;
+	msg.msg_iov[0].iov_len = sizeof(header);
+
+	pthread_mutex_lock(&handle->dbLock);
+
+	int nrUdpLists = arrayList_size(handle->udpPartLists);
+	int i;
+	bool found = false;
+	for(i = 0; i < nrUdpLists; i++) {
+		udpPartList_pt udpPartList = arrayList_get(handle->udpPartLists, i);
+		if(udpPartList->msg_ident == header.msg_ident) {
+			found = true;
+
+			//sanity check
+			if(udpPartList->msg_size != header.total_msg_size) {
+				// Corruption occurred. Remove the existing administration and build up a new one.
+				arrayList_remove(handle->udpPartLists, i);
+				free(udpPartList->data);
+				free(udpPartList);
+				found = false;
+				break;
+			}
+
+			msg.msg_iov[1].iov_base = &udpPartList->data[header.offset];
+			msg.msg_iov[1].iov_len = header.part_msg_size;
+			if(recvmsg(fd, &msg, 0)<0){
+				found=true;
+				result=false;
+				break;
+			}
+
+			udpPartList->nrPartsRemaining--;
+			if(udpPartList->nrPartsRemaining == 0) {
+				*index = i;
+				*size = udpPartList->msg_size;
+				result = true;
+				break;
+			} else {
+				result = false; // not complete
+				break;
+			}
+		}
+	}
+
+	if(found == false) {
+		udpPartList_pt udpPartList = NULL;
+		if(nrUdpLists == handle->maxNrLists) {
+			// remove list at index 0
+			udpPartList = arrayList_remove(handle->udpPartLists, 0);
+			fprintf(stderr, "ERROR: Removing entry for id %d: %d parts not received\n",udpPartList->msg_ident, udpPartList->nrPartsRemaining );
+			free(udpPartList->data);
+			free(udpPartList);
+			nrUdpLists--;
+		}
+		udpPartList = calloc(sizeof(*udpPartList), 1);
+		udpPartList->msg_ident =  header.msg_ident;
+		udpPartList->msg_size =  header.total_msg_size;
+		udpPartList->nrPartsRemaining = header.total_msg_size / MAX_PART_SIZE;
+		udpPartList->data = calloc(sizeof(char), header.total_msg_size);
+
+		msg.msg_iov[1].iov_base = &udpPartList->data[header.offset];
+		msg.msg_iov[1].iov_len = header.part_msg_size;
+		if(recvmsg(fd, &msg, 0)<0){
+			free(udpPartList->data);
+			free(udpPartList);
+			result=false;
+		}
+		else{
+			arrayList_add(handle->udpPartLists, udpPartList);
+
+			if(udpPartList->nrPartsRemaining == 0) {
+				*index = nrUdpLists;
+				*size = udpPartList->msg_size;
+				result = true;
+			} else {
+				result = false;
+			}
+		}
+
+	}
+
+	pthread_mutex_unlock(&handle->dbLock);
+
+	return result;
+}
+
+//
+// Read out the message which is indicated available by the largeUdp_dataAvailable function
+//
+int largeUdp_read(largeUdp_pt handle, unsigned int index, void ** buffer, unsigned int size)
+{
+	int result = 0;
+	pthread_mutex_lock(&handle->dbLock);
+
+	udpPartList_pt udpPartList = arrayList_remove(handle->udpPartLists, index);
+	if(udpPartList) {
+		*buffer = udpPartList->data;
+		free(udpPartList);
+	} else {
+		result = -1;
+	}
+	pthread_mutex_unlock(&handle->dbLock);
+
+	return result;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/large_udp.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/large_udp.h b/pubsub/pubsub_admin_udp_mc/src/large_udp.h
new file mode 100644
index 0000000..a21e654
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/large_udp.h
@@ -0,0 +1,45 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * large_udp.h
+ *
+ *  \date       Mar 1, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef _LARGE_UDP_H_
+#define _LARGE_UDP_H_
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+typedef struct largeUdp  *largeUdp_pt;
+
+largeUdp_pt largeUdp_create(unsigned int maxNrUdpReceptions);
+void largeUdp_destroy(largeUdp_pt handle);
+
+int largeUdp_sendto(largeUdp_pt handle, int fd, void *buf, size_t count, int flags, struct sockaddr_in *dest_addr, size_t addrlen);
+int largeUdp_sendmsg(largeUdp_pt handle, int fd, struct iovec *largeMsg_iovec, int len, int flags, struct sockaddr_in *dest_addr, size_t addrlen);
+bool largeUdp_dataAvailable(largeUdp_pt handle, int fd, unsigned int *index, unsigned int *size);
+int largeUdp_read(largeUdp_pt handle, unsigned int index, void ** buffer, unsigned int size);
+
+#endif /* _LARGE_UDP_H_ */