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 2018/05/27 18:37:25 UTC

[42/51] [partial] celix git commit: CELIX-424: Cleans up the directory structure. Moves all libraries to the libs subdir and all bundles to the bundles subdir

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log_helper.c
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log_helper.c b/bundles/log_service/src/log_helper.c
new file mode 100644
index 0000000..c0cd309
--- /dev/null
+++ b/bundles/log_service/src/log_helper.c
@@ -0,0 +1,211 @@
+/**
+ *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.
+ */
+/*
+ * log_helper.c
+ *
+ *  \date       Nov 10, 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "bundle_context.h"
+#include "service_tracker.h"
+#include "celix_threads.h"
+#include "array_list.h"
+
+#include "celix_errno.h"
+#include "log_service.h"
+
+#include "log_helper.h"
+
+#define LOGHELPER_ENABLE_STDOUT_FALLBACK_PROPERTY_NAME 	"LOGHELPER_ENABLE_STDOUT_FALLBACK"
+
+
+struct log_helper {
+	bundle_context_pt bundleContext;
+    service_tracker_pt logServiceTracker;
+	celix_thread_mutex_t logListLock;
+	array_list_pt logServices;
+	bool stdOutFallback;
+};
+
+celix_status_t logHelper_logServiceAdded(void *handle, service_reference_pt reference, void *service);
+celix_status_t logHelper_logServiceRemoved(void *handle, service_reference_pt reference, void *service);
+
+
+celix_status_t logHelper_create(bundle_context_pt context, log_helper_pt* loghelper)
+{
+	celix_status_t status = CELIX_SUCCESS;
+
+	(*loghelper) = calloc(1, sizeof(**loghelper));
+
+	if (!(*loghelper))
+	{
+		status = CELIX_ENOMEM;
+	}
+	else
+	{
+		const char* stdOutFallbackStr = NULL;
+		(*loghelper)->bundleContext = context;
+		(*loghelper)->logServiceTracker = NULL;
+		(*loghelper)->stdOutFallback = false;
+
+		bundleContext_getProperty(context, LOGHELPER_ENABLE_STDOUT_FALLBACK_PROPERTY_NAME, &stdOutFallbackStr);
+
+		if (stdOutFallbackStr != NULL) {
+			(*loghelper)->stdOutFallback = true;
+		}
+
+		pthread_mutex_init(&(*loghelper)->logListLock, NULL);
+        arrayList_create(&(*loghelper)->logServices);
+	}
+
+	return status;
+}
+
+celix_status_t logHelper_start(log_helper_pt loghelper)
+{
+	celix_status_t status;
+	service_tracker_customizer_pt logTrackerCustomizer = NULL;
+
+	status = serviceTrackerCustomizer_create(loghelper, NULL, logHelper_logServiceAdded, NULL, logHelper_logServiceRemoved, &logTrackerCustomizer);
+
+	if (status == CELIX_SUCCESS) {
+        loghelper->logServiceTracker = NULL;
+		status = serviceTracker_create(loghelper->bundleContext, (char*) OSGI_LOGSERVICE_NAME, logTrackerCustomizer, &loghelper->logServiceTracker);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_open(loghelper->logServiceTracker);
+	}
+
+	return status;
+}
+
+
+
+celix_status_t logHelper_logServiceAdded(void *handle, service_reference_pt reference, void *service)
+{
+	log_helper_pt loghelper = handle;
+
+	pthread_mutex_lock(&loghelper->logListLock);
+	arrayList_add(loghelper->logServices, service);
+	pthread_mutex_unlock(&loghelper->logListLock);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t logHelper_logServiceRemoved(void *handle, service_reference_pt reference, void *service)
+{
+	log_helper_pt loghelper = handle;
+
+	pthread_mutex_lock(&loghelper->logListLock);
+	arrayList_removeElement(loghelper->logServices, service);
+	pthread_mutex_unlock(&loghelper->logListLock);
+
+	return CELIX_SUCCESS;
+}
+
+
+celix_status_t logHelper_stop(log_helper_pt loghelper) {
+	celix_status_t status;
+
+    status = serviceTracker_close(loghelper->logServiceTracker);
+
+    return status;
+}
+
+celix_status_t logHelper_destroy(log_helper_pt* loghelper) {
+        celix_status_t status = CELIX_SUCCESS;
+
+        if((*loghelper)->logServiceTracker){
+      		serviceTracker_destroy((*loghelper)->logServiceTracker);
+        }
+
+        pthread_mutex_lock(&(*loghelper)->logListLock);
+        arrayList_destroy((*loghelper)->logServices);
+    	pthread_mutex_unlock(&(*loghelper)->logListLock);
+
+        pthread_mutex_destroy(&(*loghelper)->logListLock);
+
+        free(*loghelper);
+        *loghelper = NULL;
+        return status;
+}
+
+
+
+
+celix_status_t logHelper_log(log_helper_pt loghelper, log_level_t level, char* message, ... )
+{
+    celix_status_t status = CELIX_SUCCESS;
+	va_list listPointer;
+    char msg[1024];
+    msg[0] = '\0';
+    bool logged = false;
+
+    if(loghelper == NULL){
+	return CELIX_ILLEGAL_ARGUMENT;
+    }
+
+	va_start(listPointer, message);
+	vsnprintf(msg, 1024, message, listPointer);
+
+	pthread_mutex_lock(&loghelper->logListLock);
+
+	int i = 0;
+	for (; i < arrayList_size(loghelper->logServices); i++) {
+		log_service_pt logService = arrayList_get(loghelper->logServices, i);
+		if (logService != NULL) {
+			(logService->log)(logService->logger, level, msg);
+			logged = true;
+		}
+	}
+
+	pthread_mutex_unlock(&loghelper->logListLock);
+
+    if (!logged && loghelper->stdOutFallback) {
+        char *levelStr = NULL;
+
+        switch (level) {
+            case OSGI_LOGSERVICE_ERROR:
+                levelStr = "ERROR";
+                break;
+            case OSGI_LOGSERVICE_WARNING:
+                levelStr = "WARNING";
+                break;
+            case OSGI_LOGSERVICE_INFO:
+                levelStr = "INFO";
+                break;
+            case OSGI_LOGSERVICE_DEBUG:
+            default:
+                levelStr = "DEBUG";
+                break;
+        }
+
+        printf("%s: %s\n", levelStr, msg);
+    }
+
+    va_end(listPointer);
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log_reader_service_impl.c
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log_reader_service_impl.c b/bundles/log_service/src/log_reader_service_impl.c
new file mode 100644
index 0000000..2a46ea7
--- /dev/null
+++ b/bundles/log_service/src/log_reader_service_impl.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.
+ */
+ /*
+ * log_reader_service_impl.c
+ *
+ *  \date       Jun 26, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <stddef.h>
+
+#include "log_reader_service_impl.h"
+#include "celixbool.h"
+
+struct log_reader_data {
+    log_pt log;
+};
+
+celix_status_t logReaderService_create(log_pt log, log_reader_data_pt *reader) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *reader = (log_reader_data_pt) calloc(1, sizeof(**reader));
+
+    if (*reader == NULL) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*reader)->log = log;
+    }
+
+    return status;
+}
+
+celix_status_t logReaderService_destroy(log_reader_data_pt *reader) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    free(*reader);
+    reader = NULL;
+
+    return status;
+}
+
+
+
+celix_status_t logReaderService_getLog(log_reader_data_pt reader, linked_list_pt *list) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    status = log_getEntries(reader->log, list);
+
+    return status;
+}
+
+celix_status_t logReaderService_addLogListener(log_reader_data_pt reader, log_listener_pt listener) {
+    return log_addLogListener(reader->log, listener);
+}
+
+celix_status_t logReaderService_removeLogListener(log_reader_data_pt reader, log_listener_pt listener) {
+    return log_removeLogListener(reader->log, listener);
+}
+
+celix_status_t logReaderService_removeAllLogListener(log_reader_data_pt reader) {
+    return log_removeAllLogListener(reader->log);
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log_reader_service_impl.h
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log_reader_service_impl.h b/bundles/log_service/src/log_reader_service_impl.h
new file mode 100644
index 0000000..71829f2
--- /dev/null
+++ b/bundles/log_service/src/log_reader_service_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.
+ */
+/*
+ * log_reader_service_impl.h
+ *
+ *  \date       Jun 26, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef LOG_READER_SERVICE_IMPL_H_
+#define LOG_READER_SERVICE_IMPL_H_
+
+#include "log_reader_service.h"
+#include "log.h"
+
+celix_status_t logReaderService_create(log_pt log, log_reader_data_pt *reader);
+celix_status_t logReaderService_destroy(log_reader_data_pt *reader);
+
+celix_status_t logReaderService_getLog(log_reader_data_pt reader, linked_list_pt *list);
+
+celix_status_t logReaderService_addLogListener(log_reader_data_pt reader, log_listener_pt listener);
+celix_status_t logReaderService_removeLogListener(log_reader_data_pt reader, log_listener_pt listener);
+celix_status_t logReaderService_removeAllLogListener(log_reader_data_pt reader);
+
+
+#endif /* LOG_READER_SERVICE_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log_service_activator.c
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log_service_activator.c b/bundles/log_service/src/log_service_activator.c
new file mode 100644
index 0000000..8c72fb1
--- /dev/null
+++ b/bundles/log_service/src/log_service_activator.c
@@ -0,0 +1,198 @@
+/**
+ *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.
+ */
+/*
+ * log_service_activator.c
+ *
+ *  \date       Jun 25, 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 "bundle_activator.h"
+#include "log_service_impl.h"
+#include "service_factory.h"
+#include "log_factory.h"
+#include "log.h"
+#include "log_reader_service_impl.h"
+#include "service_registration.h"
+
+#define DEFAULT_MAX_SIZE 100
+#define DEFAULT_STORE_DEBUG false
+
+#define MAX_SIZE_PROPERTY "CELIX_LOG_MAX_SIZE"
+#define STORE_DEBUG_PROPERTY "CELIX_LOG_STORE_DEBUG"
+
+struct logActivator {
+    bundle_context_pt bundleContext;
+    service_registration_pt logServiceFactoryReg;
+    service_registration_pt logReaderServiceReg;
+
+    bundle_listener_pt bundleListener;
+    framework_listener_pt frameworkListener;
+
+    log_pt logger;
+    service_factory_pt factory;
+    log_reader_data_pt reader;
+    log_reader_service_pt reader_service;
+};
+
+static celix_status_t bundleActivator_getMaxSize(struct logActivator *activator, int *max_size);
+static celix_status_t bundleActivator_getStoreDebug(struct logActivator *activator, bool *store_debug);
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+    celix_status_t status = CELIX_SUCCESS;
+	struct logActivator * activator = NULL;
+
+    activator = (struct logActivator *) calloc(1, sizeof(struct logActivator));
+
+    if (activator == NULL) {
+        status = CELIX_ENOMEM;
+    } else {
+		activator->bundleContext = context;
+		activator->logServiceFactoryReg = NULL;
+		activator->logReaderServiceReg = NULL;
+
+		activator->logger = NULL;
+		activator->factory = NULL;
+		activator->reader = NULL;
+		activator->reader_service = NULL;
+
+        *userData = activator;
+    }
+
+    return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+    struct logActivator * activator = (struct logActivator *) userData;
+    celix_status_t status = CELIX_SUCCESS;
+
+    int max_size = 0;
+    bool store_debug = false;
+
+    bundleActivator_getMaxSize(activator, &max_size);
+    bundleActivator_getStoreDebug(activator, &store_debug);
+
+    log_create(max_size, store_debug, &activator->logger);
+
+    // Add logger as Bundle- and FrameworkEvent listener
+    activator->bundleListener = calloc(1, sizeof(*activator->bundleListener));
+    activator->bundleListener->handle = activator->logger;
+    activator->bundleListener->bundleChanged = log_bundleChanged;
+    bundleContext_addBundleListener(context, activator->bundleListener);
+
+    activator->frameworkListener = calloc(1, sizeof(*activator->frameworkListener));
+    activator->frameworkListener->handle = activator->logger;
+    activator->frameworkListener->frameworkEvent = log_frameworkEvent;
+    bundleContext_addFrameworkListener(context, activator->frameworkListener);
+
+    logFactory_create(activator->logger, &activator->factory);
+
+	properties_pt props = properties_create();
+	properties_set(props, CELIX_FRAMEWORK_SERVICE_LANGUAGE, CELIX_FRAMEWORK_SERVICE_C_LANGUAGE);
+
+
+	bundleContext_registerServiceFactory(context, (char *) OSGI_LOGSERVICE_NAME, activator->factory, props, &activator->logServiceFactoryReg);
+
+    logReaderService_create(activator->logger, &activator->reader);
+
+    activator->reader_service = calloc(1, sizeof(*activator->reader_service));
+    activator->reader_service->reader = activator->reader;
+    activator->reader_service->getLog = logReaderService_getLog;
+    activator->reader_service->addLogListener = logReaderService_addLogListener;
+    activator->reader_service->removeLogListener = logReaderService_removeLogListener;
+    activator->reader_service->removeAllLogListener = logReaderService_removeAllLogListener;
+
+	props = properties_create();
+	properties_set(props, CELIX_FRAMEWORK_SERVICE_LANGUAGE, CELIX_FRAMEWORK_SERVICE_C_LANGUAGE);
+
+    bundleContext_registerService(context, (char *) OSGI_LOGSERVICE_READER_SERVICE_NAME, activator->reader_service, props, &activator->logReaderServiceReg);
+
+    return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	struct logActivator * activator = (struct logActivator *) userData;
+
+	serviceRegistration_unregister(activator->logReaderServiceReg);
+	activator->logReaderServiceReg = NULL;
+	serviceRegistration_unregister(activator->logServiceFactoryReg);
+	activator->logServiceFactoryReg = NULL;
+
+    logReaderService_destroy(&activator->reader);
+	free(activator->reader_service);
+
+	logFactory_destroy(&activator->factory);
+
+	bundleContext_removeBundleListener(context, activator->bundleListener);
+	bundleContext_removeFrameworkListener(context, activator->frameworkListener);
+
+	free(activator->bundleListener);
+	free(activator->frameworkListener);
+
+	log_destroy(activator->logger);
+
+    return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	struct logActivator * activator = (struct logActivator *) userData;
+
+	free(activator);
+
+    return CELIX_SUCCESS;
+}
+
+static celix_status_t bundleActivator_getMaxSize(struct logActivator *activator, int *max_size) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	const char *max_size_str = NULL;
+
+	*max_size = DEFAULT_MAX_SIZE;
+
+	bundleContext_getProperty(activator->bundleContext, MAX_SIZE_PROPERTY, &max_size_str);
+	if (max_size_str) {
+		*max_size = atoi(max_size_str);
+	}
+
+	return status;
+}
+
+static celix_status_t bundleActivator_getStoreDebug(struct logActivator *activator, bool *store_debug) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	const char *store_debug_str = NULL;
+
+	*store_debug = DEFAULT_STORE_DEBUG;
+
+	bundleContext_getProperty(activator->bundleContext, STORE_DEBUG_PROPERTY, &store_debug_str);
+	if (store_debug_str) {
+		if (strcasecmp(store_debug_str, "true") == 0) {
+			*store_debug = true;
+		} else if (strcasecmp(store_debug_str, "false") == 0) {
+			*store_debug = false;
+		}
+	}
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log_service_impl.c
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log_service_impl.c b/bundles/log_service/src/log_service_impl.c
new file mode 100644
index 0000000..a77e9ad
--- /dev/null
+++ b/bundles/log_service/src/log_service_impl.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.
+ */
+/*
+ * log_service_impl.c
+ *
+ *  \date       Jun 22, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "log_service_impl.h"
+#include "module.h"
+#include "bundle.h"
+
+struct log_service_data {
+    log_pt log;
+    bundle_pt bundle;
+};
+
+celix_status_t logService_create(log_pt log, bundle_pt bundle, log_service_data_pt *logger) {
+    celix_status_t status = CELIX_SUCCESS;
+    *logger = calloc(1, sizeof(struct log_service_data));
+    if (*logger == NULL) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*logger)->bundle = bundle;
+        (*logger)->log = log;
+    }
+
+    return status;
+}
+
+celix_status_t logService_destroy(log_service_data_pt *logger) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    free(*logger);
+    logger = NULL;
+
+    return status;
+}
+
+celix_status_t logService_log(log_service_data_pt logger, log_level_t level, char * message) {
+    return logService_logSr(logger, NULL, level, message);
+}
+
+celix_status_t logService_logSr(log_service_data_pt logger, service_reference_pt reference, log_level_t level, char * message) {
+    celix_status_t status;
+    log_entry_pt entry = NULL;
+    bundle_pt bundle = logger->bundle;
+    bundle_archive_pt archive = NULL;
+    module_pt module = NULL;
+    const char *symbolicName = NULL;
+    long bundleId = -1;
+
+    if (reference != NULL) {
+    	serviceReference_getBundle(reference, &bundle);
+    }
+
+    status = bundle_getArchive(bundle, &archive);
+
+    if (status == CELIX_SUCCESS) {
+        status = bundleArchive_getId(archive, &bundleId);
+    }
+
+    if (status == CELIX_SUCCESS) {
+        status = bundle_getCurrentModule(bundle, &module);
+
+        if (status == CELIX_SUCCESS) {
+            status = module_getSymbolicName(module, &symbolicName);
+        }
+    }
+
+    if(status == CELIX_SUCCESS && symbolicName != NULL && message != NULL){
+	status = logEntry_create(bundleId, symbolicName, reference, level, message, 0, &entry);
+	log_addEntry(logger->log, entry);
+    }
+
+    return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log_service_impl.h
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log_service_impl.h b/bundles/log_service/src/log_service_impl.h
new file mode 100644
index 0000000..04c986e
--- /dev/null
+++ b/bundles/log_service/src/log_service_impl.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.
+ */
+/*
+ * log_service_impl.h
+ *
+ *  \date       Jun 22, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef LOG_SERVICE_IMPL_H_
+#define LOG_SERVICE_IMPL_H_
+
+#include "log_service.h"
+#include "log.h"
+
+celix_status_t logService_create(log_pt log, bundle_pt bundle, log_service_data_pt *logger);
+celix_status_t logService_destroy(log_service_data_pt *logger);
+celix_status_t logService_log(log_service_data_pt logger, log_level_t level, char * message);
+celix_status_t logService_logSr(log_service_data_pt logger, service_reference_pt reference, log_level_t level, char * message);
+
+
+#endif /* LOG_SERVICE_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_writer/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/log_writer/CMakeLists.txt b/bundles/log_writer/CMakeLists.txt
new file mode 100644
index 0000000..329de94
--- /dev/null
+++ b/bundles/log_writer/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.
+
+celix_subproject(LOG_WRITER "Option to enable building the Log Writer bundles" ON DEPS FRAMEWORK LOG_SERVICE)
+if (LOG_WRITER)
+    add_subdirectory(log_writer)
+    add_subdirectory(log_writer_stdout)
+    add_subdirectory(log_writer_syslog)
+
+endif (LOG_WRITER)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_writer/README.md
----------------------------------------------------------------------
diff --git a/bundles/log_writer/README.md b/bundles/log_writer/README.md
new file mode 100644
index 0000000..e2d5b34
--- /dev/null
+++ b/bundles/log_writer/README.md
@@ -0,0 +1,13 @@
+# 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
+    BUILD_LOG_WRITER=ON
+    BUILD_LOG_WRITER_SYSLOG=ON
+
+## Using info
+
+If the Celix Log Writers are installed `find_package(CELIX)` 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/3bce889b/bundles/log_writer/log_writer/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/log_writer/log_writer/CMakeLists.txt b/bundles/log_writer/log_writer/CMakeLists.txt
new file mode 100644
index 0000000..cc6b8eb
--- /dev/null
+++ b/bundles/log_writer/log_writer/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(log_writer_common STATIC
+		src/log_writer.c
+		src/log_writer_activator.c
+)
+target_include_directories(log_writer_common PRIVATE src)
+target_include_directories(log_writer_common PUBLIC include)
+target_link_libraries(log_writer_common PUBLIC Celix::log_service_api Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_writer/log_writer/include/log_writer.h
----------------------------------------------------------------------
diff --git a/bundles/log_writer/log_writer/include/log_writer.h b/bundles/log_writer/log_writer/include/log_writer.h
new file mode 100644
index 0000000..b4b70d0
--- /dev/null
+++ b/bundles/log_writer/log_writer/include/log_writer.h
@@ -0,0 +1,53 @@
+/**
+ *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.
+ */
+/*
+ * log_writer.h
+ *
+ *  \date       Jul 4, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef LOG_WRITER_H_
+#define LOG_WRITER_H_
+
+#include "log_reader_service.h"
+#include "service_tracker.h"
+
+struct log_writer {
+    log_reader_service_pt logReader;
+    log_listener_pt logListener;
+
+    bundle_context_pt context;
+    service_tracker_pt tracker;
+};
+
+typedef struct log_writer *log_writer_pt;
+
+celix_status_t logWriter_create(bundle_context_pt context, log_writer_pt *writer);
+celix_status_t logWriter_destroy(log_writer_pt *writer);
+celix_status_t logWriter_start(log_writer_pt writer);
+celix_status_t logWriter_stop(log_writer_pt writer);
+
+celix_status_t logWriter_addingServ(void * handle, service_reference_pt ref, void **service);
+celix_status_t logWriter_addedServ(void * handle, service_reference_pt ref, void * service);
+celix_status_t logWriter_modifiedServ(void * handle, service_reference_pt ref, void * service);
+celix_status_t logWriter_removedServ(void * handle, service_reference_pt ref, void * service);
+
+#endif /* LOG_WRITER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_writer/log_writer/src/log_writer.c
----------------------------------------------------------------------
diff --git a/bundles/log_writer/log_writer/src/log_writer.c b/bundles/log_writer/log_writer/src/log_writer.c
new file mode 100644
index 0000000..685c1a5
--- /dev/null
+++ b/bundles/log_writer/log_writer/src/log_writer.c
@@ -0,0 +1,122 @@
+/**
+ *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.
+ */
+/*
+ * log_writer.c
+ *
+ *  \date       Mar 7, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "celix_errno.h"
+#include "celixbool.h"
+
+#include "log_writer.h"
+#include "log_listener.h"
+#include "module.h"
+#include "bundle.h"
+
+celix_status_t logWriter_create(bundle_context_pt context, log_writer_pt *writer) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*writer = calloc(1, sizeof(**writer));
+	(*writer)->logListener = calloc(1, sizeof(*(*writer)->logListener));
+	(*writer)->logListener->handle = *writer;
+	(*writer)->logListener->logged = logListener_logged;
+	(*writer)->logReader = NULL;
+	(*writer)->context = context;
+	(*writer)->tracker = NULL;
+
+	return status;
+}
+
+
+celix_status_t logWriter_destroy(log_writer_pt *writer) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	free((*writer)->logListener);
+	free(*writer);
+
+	writer = NULL;
+
+	return status;
+}
+celix_status_t logWriter_start(log_writer_pt writer) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	service_tracker_customizer_pt cust = NULL;
+	service_tracker_pt tracker = NULL;
+
+	status = serviceTrackerCustomizer_create(writer, logWriter_addingServ, logWriter_addedServ, logWriter_modifiedServ, logWriter_removedServ, &cust);
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(writer->context, (char *) OSGI_LOGSERVICE_READER_SERVICE_NAME, cust, &tracker);
+		if (status == CELIX_SUCCESS) {
+			writer->tracker = tracker;
+			status = serviceTracker_open(tracker);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t logWriter_stop(log_writer_pt writer) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (serviceTracker_close(writer->tracker) != CELIX_SUCCESS) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	}
+	if (serviceTracker_destroy(writer->tracker) != CELIX_SUCCESS) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	}
+
+	return status;
+}
+
+celix_status_t logWriter_addingServ(void * handle, service_reference_pt ref, void **service) {
+	log_writer_pt writer = (log_writer_pt) handle;
+	bundleContext_getService(writer->context, ref, service);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t logWriter_addedServ(void * handle, service_reference_pt ref, void * service) {
+	log_writer_pt writer = (log_writer_pt) handle;
+
+	// Add this writer to each log reader service found
+	if (service != NULL) {
+		((log_reader_service_pt) service)->addLogListener(((log_reader_service_pt) service)->reader, writer->logListener);
+	}
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t logWriter_modifiedServ(void * handle, service_reference_pt ref, void * service) {
+	return CELIX_SUCCESS;
+}
+
+celix_status_t logWriter_removedServ(void * handle, service_reference_pt ref, void * service) {
+	log_writer_pt writer = (log_writer_pt) handle;
+
+	if (service != NULL) {
+		((log_reader_service_pt) service)->removeLogListener(((log_reader_service_pt) service)->reader, writer->logListener);
+	}
+
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_writer/log_writer/src/log_writer_activator.c
----------------------------------------------------------------------
diff --git a/bundles/log_writer/log_writer/src/log_writer_activator.c b/bundles/log_writer/log_writer/src/log_writer_activator.c
new file mode 100644
index 0000000..248cad6
--- /dev/null
+++ b/bundles/log_writer/log_writer/src/log_writer_activator.c
@@ -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.
+ */
+/*
+ * log_writer_activator.c
+ *
+ *  \date       Oct 1, 2013
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#include "log_writer.h"
+
+#include "bundle_activator.h"
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	log_writer_pt writer = NULL;
+
+	logWriter_create(context, &writer);
+
+	*userData = writer;
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	log_writer_pt writer = (log_writer_pt) userData;
+
+	return logWriter_start(writer);
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	log_writer_pt writer = (log_writer_pt) userData;
+
+	return logWriter_stop(writer);
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	log_writer_pt writer = (log_writer_pt) userData;
+
+	return logWriter_destroy(&writer);
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_writer/log_writer_stdout/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/log_writer/log_writer_stdout/CMakeLists.txt b/bundles/log_writer/log_writer_stdout/CMakeLists.txt
new file mode 100644
index 0000000..baebd73
--- /dev/null
+++ b/bundles/log_writer/log_writer_stdout/CMakeLists.txt
@@ -0,0 +1,41 @@
+# 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_celix_bundle(log_writer_stdout
+	SYMBOLIC_NAME "apache_celix_log_writer"
+	VERSION "1.1.0"
+	NAME "Apache Celix Log Writer"
+	SOURCES
+		src/log_writer_stdout
+)
+
+IF(APPLE)
+	target_link_libraries(log_writer_stdout PRIVATE -Wl,-all_load log_writer_common)
+else()
+	if(ENABLE_ADDRESS_SANITIZER)
+		#With asan there can be undefined symbols
+		target_link_libraries(log_writer_stdout PRIVATE -Wl,--whole-archive log_writer_common -Wl,--no-whole-archive)
+	else()
+		target_link_libraries(log_writer_stdout PRIVATE -Wl,--no-undefined -Wl,--whole-archive log_writer_common -Wl,--no-whole-archive)
+	endif()
+endif()
+
+target_link_libraries(log_writer_stdout PRIVATE Celix::log_service_api)
+
+install_celix_bundle(log_writer_stdout EXPORT celix)
+add_library(Celix::log_writer_stdout ALIAS log_writer_stdout)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_writer/log_writer_stdout/src/log_writer_stdout.c
----------------------------------------------------------------------
diff --git a/bundles/log_writer/log_writer_stdout/src/log_writer_stdout.c b/bundles/log_writer/log_writer_stdout/src/log_writer_stdout.c
new file mode 100644
index 0000000..d57e5d5
--- /dev/null
+++ b/bundles/log_writer/log_writer_stdout/src/log_writer_stdout.c
@@ -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.
+ */
+/*
+ * log_writer_stdout.c
+ *
+ *  \date       Mar 7, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "celix_errno.h"
+#include "celixbool.h"
+
+#include "log_writer.h"
+#include "log_listener.h"
+
+#include "module.h"
+#include "bundle.h"
+
+celix_status_t logListener_logged(log_listener_pt listener, log_entry_pt entry) {
+	celix_status_t status = CELIX_SUCCESS;
+
+    if (!entry) {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    } else {
+		printf("LogWriter: %s from %s\n", entry->message, entry->bundleSymbolicName);
+    }
+
+    return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_writer/log_writer_syslog/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/log_writer/log_writer_syslog/CMakeLists.txt b/bundles/log_writer/log_writer_syslog/CMakeLists.txt
new file mode 100644
index 0000000..9a9d690
--- /dev/null
+++ b/bundles/log_writer/log_writer_syslog/CMakeLists.txt
@@ -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.
+celix_subproject(LOG_WRITER_SYSLOG "Option to enable building the Syslog Writer" OFF DEPS FRAMEWORK LOG_SERVICE)
+if (LOG_WRITER_SYSLOG)
+    find_package(Syslog REQUIRED)
+
+    add_celix_bundle(log_writer_syslog
+        VERSION 1.1.0
+        SYMBOLIC_NAME "apache_celix_log_writer_syslog"
+        NAME "Apache Celix Log Writer Syslog"
+        SOURCES
+            private/src/log_writer_syslog
+    )
+
+    IF(APPLE)
+        target_link_libraries(log_writer_syslog PRIVATE -Wl,-all_load log_writer_common)
+    else()
+        if(ENABLE_ADDRESS_SANITIZER)
+            #With asan there can be undefined symbols
+            target_link_libraries(log_writer_syslog PRIVATE -Wl,--whole-archive log_writer_common -Wl,--no-whole-archive)
+        else()
+            target_link_libraries(log_writer_syslog PRIVATE -Wl,--no-undefined -Wl,--whole-archive log_writer_common -Wl,--no-whole-archive)
+        endif()
+    endif()
+
+    target_link_libraries(log_writer_syslog PRIVATE Celix::log_service_ap)
+
+    install_celix_bundle(log_writer_syslog EXPORT celix)
+    add_library(Celix::log_writer_syslog ALIAS log_writer_syslog)
+endif (LOG_WRITER_SYSLOG)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_writer/log_writer_syslog/private/src/log_writer_syslog.c
----------------------------------------------------------------------
diff --git a/bundles/log_writer/log_writer_syslog/private/src/log_writer_syslog.c b/bundles/log_writer/log_writer_syslog/private/src/log_writer_syslog.c
new file mode 100644
index 0000000..c5a35ea
--- /dev/null
+++ b/bundles/log_writer/log_writer_syslog/private/src/log_writer_syslog.c
@@ -0,0 +1,68 @@
+/**
+ *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.
+ */
+/*
+ * log_writer_syslog.c
+ *
+ *  \date       Mar 7, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "celix_errno.h"
+#include "celixbool.h"
+
+#include "log_writer.h"
+#include "log_listener.h"
+
+#include "module.h"
+#include "bundle.h"
+
+#include <syslog.h>
+
+celix_status_t logListener_logged(log_listener_pt listener, log_entry_pt entry)
+{
+	celix_status_t status = CELIX_SUCCESS;
+
+	int sysLogLvl = -1;
+
+	switch(entry->level)
+	{
+		case 0x00000001: /*OSGI_LOGSERVICE_ERROR */
+			sysLogLvl = LOG_MAKEPRI(LOG_FAC(LOG_USER), LOG_ERR);
+			break;
+		case 0x00000002: /* OSGI_LOGSERVICE_WARNING */
+			sysLogLvl = LOG_MAKEPRI(LOG_FAC(LOG_USER), LOG_WARNING);
+			break;
+		case 0x00000003: /* OSGI_LOGSERVICE_INFO */
+			sysLogLvl = LOG_MAKEPRI(LOG_FAC(LOG_USER), LOG_INFO);
+			break;
+		case 0x00000004: /* OSGI_LOGSERVICE_DEBUG */
+			sysLogLvl = LOG_MAKEPRI(LOG_FAC(LOG_USER), LOG_DEBUG);
+			break;
+		default:		/* OSGI_LOGSERVICE_INFO */
+			sysLogLvl = LOG_MAKEPRI(LOG_FAC(LOG_USER), LOG_INFO);
+			break;
+	}
+
+	syslog(sysLogLvl, "[%s]: %s", entry->bundleSymbolicName, entry->message);
+
+    return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/CMakeLists.txt b/bundles/pubsub/CMakeLists.txt
new file mode 100644
index 0000000..e3db995
--- /dev/null
+++ b/bundles/pubsub/CMakeLists.txt
@@ -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.
+
+celix_subproject(PUBSUB "Option to build the pubsub bundles" OFF DEPS UTILS)
+if (PUBSUB)
+
+    option(BUILD_PUBSUB_PSA_ZMQ "Build ZeroMQ PubSub Admin (LGPL License)" OFF)
+    if (BUILD_PUBSUB_PSA_ZMQ)
+		message(WARNING "Celix will now contain a dependency with a LGPL License (ZeroMQ). For more information about this, consult the pubsub/README.md file.")
+		option(BUILD_ZMQ_SECURITY "Build with security for ZeroMQ." OFF)
+    endif (BUILD_PUBSUB_PSA_ZMQ)
+
+	add_subdirectory(pubsub_api)
+	add_subdirectory(pubsub_spi)
+	add_subdirectory(pubsub_topology_manager)
+	add_subdirectory(pubsub_discovery)
+	add_subdirectory(pubsub_serializer_json)
+	add_subdirectory(pubsub_admin_zmq)
+	add_subdirectory(pubsub_admin_udp_mc)
+	add_subdirectory(keygen)
+	add_subdirectory(mock)
+
+	add_subdirectory(examples)
+
+	if (ENABLE_TESTING)
+		option(BUILD_PUBSUB_TESTS "Enable Tests for PUBSUB" OFF)
+	endif()
+	if (ENABLE_TESTING AND BUILD_PUBSUB_TESTS AND BUILD_PUBSUB_PSA_ZMQ)
+		add_subdirectory(test)
+	endif()
+
+endif(PUBSUB)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/README.md
----------------------------------------------------------------------
diff --git a/bundles/pubsub/README.md b/bundles/pubsub/README.md
new file mode 100644
index 0000000..ff33690
--- /dev/null
+++ b/bundles/pubsub/README.md
@@ -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.
+-->
+
+# Publisher / subscriber implementation
+
+This subdirectory contains an implementation for a publish-subscribe remote services system, that use dfi library for message serialization.
+For low-level communication, UDP and ZMQ is used.
+
+# Description
+
+This publisher / subscriber implementation is based on the concepts of the remote service admin (i.e. rsa / topology / discovery pattern).
+
+Publishers are senders of data, subscribers can receive data. Publishers can publish/send data to certain channels (called 'topics' further on), subscribers can subscribe to these topics. For every topic a publisher service is created by the pubsub admin. This publisher is announced through etcd. So etcd is used for discovery of the publishers. Subscribers are also registered as a service by the pubsub admin and will watch etcd for changes and when a new publisher is announced, the subscriber will check if the topic matches its interests. If the subscriber is interested in/subscribed to a certain topic, a connection between publisher and subscriber will be instantiated by the pubsub admin.
+
+The dfi library is used for message serialization. The publisher / subscriber implementation will arrange that every message which will be send gets an unique id. 
+
+For communication between publishers and subscribers UDP and ZeroMQ can be used. When using ZeroMQ it's also possible to setup a secure connection to encrypt the traffic being send between publishers and subscribers. This connection can be secured with ZeroMQ by using a curve25519 key pair per topic.
+
+The publisher/subscriber implementation supports sending of a single message and sending of multipart messages.
+
+## Getting started
+
+The publisher/subscriber implementation contains 2 different PubSubAdmins for managing connections:
+  * PubsubAdminUDP: This pubsub admin is using linux sockets to setup a connection. 
+  * PubsubAdminZMQ (LGPL License): This pubsub admin is using ZeroMQ and is disabled as default. This is a because the pubsub admin is using ZeroMQ which is licensed as LGPL ([View ZeroMQ License](https://github.com/zeromq/libzmq#license)).
+  
+  The ZeroMQ pubsub admin can be enabled by specifying the build flag `BUILD_PUBSUB_PSA_ZMQ=ON`. To get the ZeroMQ pubsub admin running, [ZeroMQ](https://github.com/zeromq/libzmq) and [CZMQ](https://github.com/zeromq/czmq) need to be installed. Also, to make use of encrypted traffic, [OpenSSL](https://github.com/openssl/openssl) is required.
+
+## Running instructions
+
+### Running PSA UDP-Multicast
+
+1. Open a terminal
+1. Run `etcd`
+1. Open second terminal on project build location
+1. Run `cd deploy/pubsub/pubsub_publisher_udp_mc`
+1. Run `sh run.sh`
+1. Open third terminal on project build location
+1. Run `cd deploy/pubsub/pubsub_subscriber_udp_mc`
+1. Run `sh run.sh`
+
+Design information can be found at pubsub\_admin\_udp\_mc/README.md
+
+### Running PSA ZMQ
+
+For ZeroMQ without encryption, skip the steps 1-12 below
+
+1. Run `touch ~/pubsub.keys`
+1. Run `echo "aes_key:{AES_KEY here}" >> ~/pubsub.keys`. Note that AES_KEY is just a sequence of random bytes. To generate such a key, you can use the command `cat /dev/urandom | hexdump -v -e '/1 "%02X"' | head -c 32` (this will take out of /dev/urandom 16 bytes, thus a 128bit key)
+1. Run `echo "aes_iv:{AES_IV here}" >> ~/pubsub.keys`.  Note that AES_IV is just a sequence of random bytes. To generate such an initial vector , you can use the command `cat /dev/urandom | hexdump -v -e '/1 "%02X"' | head -c 16` (this will take out of /dev/urandom 8 bytes, thus a 64bit initial vector) 
+1. Run `touch ~/pubsub.conf`
+1. Run `echo "keys.file.path=$HOME" >> ~/pubsub.conf`
+1. Run `echo "keys.file.name=pubsub.keys" >> ~/pubsub.conf`
+1. Generate ZMQ keypairs by running `pubsub/keygen/makecert pub_<topic_name>.pub pub_<topic_name>.key`
+1. Encrypt the private key file using `pubsub/keygen/ed_file ~/pubsub.keys pub_<topic_name>.key pub_<topic>.key.enc`
+1. Store the keys in the pubsub/examples/keys/ directory, as described in the pubsub/examples/keys/README.
+1. Build project to include these keys (check the CMakeLists.txt files to be sure that the keys are included in the bundles)
+1. Add to the config.properties the property SECURE_TOPICS=<list_of_secure_topics> 
+
+For ZeroMQ without encryption, start here
+
+1. Run `etcd`
+1. Open second terminal on pubsub root
+1. Run `cd deploy/pubsub/pubsub_publisher_zmq`
+1. Run `cat ~/pubsub.conf >> config.properties` (only for ZeroMQ with encryption)
+1. Run `sh run.sh`
+1. Open third terminal on pubsub root
+1. Run `cd deploy/pubsub/pubsub_subscriber_zmq`
+1. Run `cat ~/pubsub.conf >> config.properties` (only for ZeroMQ with encryption)
+1. Run `sh run.sh`
+
+### Properties PSA ZMQ
+
+Some properties can be set to configure the PSA-ZMQ. If not configured defaults will be used. These
+properties can be set in the config.properties file (<PROPERTY>=<VALUE> format)
+
+1. PSA_ZMQ_RECEIVE_TIMEOUT_MICROSEC : Set the polling interval of the ZMQ receive thread. Default 1ms
+1. PSA_IP : The local IP address to be used by the ZMQ admin to publish its data. Default te first IP not on localhost
+1. PSA_INTERFACE : The local ethernet interface to be used by the ZMQ admin to publish its data (ie eth0). Default the first non localhost interface
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/CMakeLists.txt b/bundles/pubsub/examples/CMakeLists.txt
new file mode 100644
index 0000000..91f2efa
--- /dev/null
+++ b/bundles/pubsub/examples/CMakeLists.txt
@@ -0,0 +1,247 @@
+# 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_subdirectory(pubsub)
+add_subdirectory(mp_pubsub)
+
+find_program(ETCD_CMD NAMES etcd)
+find_program(XTERM_CMD NAMES xterm)
+
+find_package(ZMQ REQUIRED)
+find_package(CZMQ REQUIRED)
+find_package(Jansson REQUIRED)
+
+set(PUBSUB_CONTAINER_LIBS ${JANSSON_LIBRARY} ${ZMQ_LIBRARIES} ${CZMQ_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARY} Celix::dfi)
+
+# UDP Multicast
+add_celix_container(pubsub_publisher_udp_mc
+        GROUP pubsub
+        BUNDLES
+        Celix::shell
+        Celix::shell_tui
+        Celix::pubsub_serializer_json
+        Celix::pubsub_discovery_etcd
+        Celix::pubsub_topology_manager
+        Celix::pubsub_admin_udp_multicast
+        celix_pubsub_poi_publisher
+        celix_pubsub_poi_publisher2
+        )
+target_link_libraries(pubsub_publisher_udp_mc PRIVATE ${PUBSUB_CONTAINER_LIBS})
+
+add_celix_container("pubsub_subscriber_udp_mc"
+        GROUP "pubsub"
+        BUNDLES
+        Celix::shell
+        Celix::shell_tui
+        Celix::pubsub_serializer_json
+        Celix::pubsub_discovery_etcd
+        Celix::pubsub_topology_manager
+        Celix::pubsub_admin_udp_multicast
+        celix_pubsub_poi_subscriber
+        )
+target_link_libraries(pubsub_subscriber_udp_mc PRIVATE ${PUBSUB_CONTAINER_LIBS})
+add_celix_container("pubsub_subscriber2_udp_mc"
+        GROUP "pubsub"
+        BUNDLES
+        Celix::shell
+        Celix::shell_tui
+        Celix::pubsub_serializer_json
+        Celix::pubsub_discovery_etcd
+        Celix::pubsub_topology_manager
+        Celix::pubsub_admin_udp_multicast
+        celix_pubsub_poi_subscriber
+        )
+target_link_libraries(pubsub_subscriber2_udp_mc PRIVATE ${PUBSUB_CONTAINER_LIBS})
+if (ETCD_CMD AND XTERM_CMD)
+    #Runtime starting a publish and subscriber for udp mc
+    add_runtime(pubsub_rt_upd_mc
+            NAME udp_mc
+            GROUP pubsub
+            DEPLOYMENTS
+            pubsub_publisher_udp_mc
+            pubsub_subscriber_udp_mc
+            pubsub_subscriber2_udp_mc
+            COMMANDS
+            etcd
+            USE_TERM
+            )
+endif ()
+
+if (BUILD_PUBSUB_PSA_ZMQ)
+
+    # Dynamic ZMQ / UDP admin
+    add_celix_container("pubsub_publisher"
+        GROUP "pubsub"
+        BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            Celix::pubsub_admin_udp_multicast
+            celix_pubsub_poi_publisher
+            celix_pubsub_poi_publisher2
+        PROPERTIES
+            poi1.psa=zmq
+            poi2.psa=udp
+    )
+    target_link_libraries(pubsub_publisher PRIVATE ${PUBSUB_CONTAINER_LIBS})
+
+    add_celix_container("pubsub_subscriber"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            Celix::pubsub_admin_udp_multicast
+            celix_pubsub_poi_subscriber
+            PROPERTIES
+            poi1.psa=zmq
+            poi2.psa=udp
+            )
+    target_link_libraries(pubsub_subscriber PRIVATE ${PUBSUB_CONTAINER_LIBS})
+
+    # ZMQ
+    add_celix_container("pubsub_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            celix_pubsub_poi_publisher
+            celix_pubsub_poi_subscriber
+            )
+    target_link_libraries(pubsub_zmq PRIVATE ${PUBSUB_CONTAINER_LIBS})
+
+    add_celix_container("pubsub_publisher_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            celix_pubsub_poi_publisher
+            celix_pubsub_poi_publisher2
+            PROPERTIES
+            pubsub.scope=my_small_scope
+            )
+    target_link_libraries(pubsub_publisher_zmq PRIVATE ${PUBSUB_CONTAINER_LIBS})
+
+    add_celix_container("pubsub_subscriber_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            celix_pubsub_poi_subscriber
+            )
+    target_link_libraries(pubsub_subscriber_zmq PRIVATE ${PUBSUB_CONTAINER_LIBS})
+
+    add_celix_container("pubsub_subscriber2_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            celix_pubsub_poi_subscriber
+
+            )
+    target_link_libraries(pubsub_subscriber2_zmq PRIVATE ${PUBSUB_CONTAINER_LIBS})
+
+    # ZMQ Multipart
+    add_celix_container("pubsub_mp_subscriber_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            org.apache.celix.pubsub_subscriber.MpSubscriber
+            )
+    target_link_libraries(pubsub_mp_subscriber_zmq PRIVATE ${PUBSUB_CONTAINER_LIBS})
+
+    add_celix_container("pubsub_mp_publisher_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            org.apache.celix.pubsub_publisher.MpPublisher
+            )
+    target_link_libraries(pubsub_mp_publisher_zmq PRIVATE ${PUBSUB_CONTAINER_LIBS})
+
+    if (ETCD_CMD AND XTERM_CMD)
+        #Runtime starting two bundles using both zmq and upd mc pubsub
+        add_runtime(pubsub_rt_zmq_udpmc_combi
+                NAME combi
+                GROUP pubsub
+                DEPLOYMENTS
+                pubsub_publisher_zmq
+                pubsub_subscriber_zmq
+                pubsub_subscriber_zmq
+                COMMANDS
+                etcd
+                USE_TERM
+                )
+
+        #Runtime starting a publish and 2 subscribers for zmq
+        add_runtime(pubsub_rt_zmq
+                NAME zmq
+                GROUP pubsub
+                DEPLOYMENTS
+                pubsub_publisher
+                pubsub_subscriber_zmq
+                pubsub_subscriber2_zmq
+                COMMANDS
+                etcd
+                USE_TERM
+                )
+
+        #Runtime starting a multipart (multiple message in one send) publish and subscriber for zmq
+        add_runtime(pubsub_rt_multipart_zmq
+                NAME zmq_multipart
+                GROUP pubsub
+                DEPLOYMENTS
+                pubsub_mp_subscriber_zmq
+                pubsub_mp_publisher_zmq
+                COMMANDS
+                etcd
+                USE_TERM
+                )
+    endif ()
+
+endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/keys/README.md
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/keys/README.md b/bundles/pubsub/examples/keys/README.md
new file mode 100644
index 0000000..200acc9
--- /dev/null
+++ b/bundles/pubsub/examples/keys/README.md
@@ -0,0 +1,36 @@
+
+<!--
+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.
+-->
+
+Store the AES key for encrypting and decrypting the encoded secret keys safe in a file!
+Default file is `/etc/pubsub.keys` with the following format:
+```
+aes_key:{32 character AES key here}
+aes_iv:{16 character AES iv here}
+```
+
+Use the $PROJECT_BUILD/pubsub/keygen/makecert for generating keypairs
+Use the $PROJECT_BUILD/pubsub/keygen/ed_file for encrypting and decrypting private keys
+
+Public keys need to be stored in the 'public' folder having the following format:
+- pub_{topic}.pub
+- sub_{topic}.pub
+
+Secret keys need to be stored in the 'private' folder having the following format:
+- pub_{topic}.key.enc
+- sub_{topic}.key.enc
+These files need to be encrypted using the 'ed_file' executable.

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/keys/publisher/private/.gitkeep
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/keys/publisher/private/.gitkeep b/bundles/pubsub/examples/keys/publisher/private/.gitkeep
new file mode 100644
index 0000000..4ea9b31
--- /dev/null
+++ b/bundles/pubsub/examples/keys/publisher/private/.gitkeep
@@ -0,0 +1,14 @@
+# 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.

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/keys/publisher/public/.gitkeep
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/keys/publisher/public/.gitkeep b/bundles/pubsub/examples/keys/publisher/public/.gitkeep
new file mode 100644
index 0000000..978b68a
--- /dev/null
+++ b/bundles/pubsub/examples/keys/publisher/public/.gitkeep
@@ -0,0 +1,16 @@
+# 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.

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/keys/subscriber/private/.gitkeep
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/keys/subscriber/private/.gitkeep b/bundles/pubsub/examples/keys/subscriber/private/.gitkeep
new file mode 100644
index 0000000..978b68a
--- /dev/null
+++ b/bundles/pubsub/examples/keys/subscriber/private/.gitkeep
@@ -0,0 +1,16 @@
+# 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.

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/keys/subscriber/public/.gitkeep
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/keys/subscriber/public/.gitkeep b/bundles/pubsub/examples/keys/subscriber/public/.gitkeep
new file mode 100644
index 0000000..978b68a
--- /dev/null
+++ b/bundles/pubsub/examples/keys/subscriber/public/.gitkeep
@@ -0,0 +1,16 @@
+# 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.

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/CMakeLists.txt b/bundles/pubsub/examples/mp_pubsub/CMakeLists.txt
new file mode 100644
index 0000000..c828832
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/CMakeLists.txt
@@ -0,0 +1,23 @@
+# 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_directories("common/include")
+
+add_subdirectory(publisher)
+add_subdirectory(subscriber)
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/common/include/ew.h
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/common/include/ew.h b/bundles/pubsub/examples/mp_pubsub/common/include/ew.h
new file mode 100644
index 0000000..81ca5f3
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/common/include/ew.h
@@ -0,0 +1,53 @@
+/**
+ *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.
+ */
+/*
+ * ew.h
+ *
+ *  \date       Jan 15, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef EW_H_
+#define EW_H_
+
+#define MIN_AREA	50.0F
+#define MAX_AREA	15000.0F
+
+#define MSG_EW_NAME	"ew" //Has to match the message name in the msg descriptor!
+
+typedef enum color{
+	GREEN,
+	BLUE,
+	RED,
+	BLACK,
+	WHITE,
+	LAST_COLOR
+} color_e;
+
+const char* color_tostring[] = {"GREEN","BLUE","RED","BLACK","WHITE"};
+
+struct ew_data{
+	double area;
+	color_e color;
+};
+
+typedef struct ew_data* ew_data_pt;
+
+#endif /* EW_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/common/include/ide.h
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/common/include/ide.h b/bundles/pubsub/examples/mp_pubsub/common/include/ide.h
new file mode 100644
index 0000000..2b9588d
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/common/include/ide.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.
+ */
+/*
+ * ide.h
+ *
+ *  \date       Jan 15, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef IDE_H_
+#define IDE_H_
+
+#define MSG_IDE_NAME	"ide" //Has to match the message name in the msg descriptor!
+
+typedef enum shape{
+	SQUARE,
+	CIRCLE,
+	TRIANGLE,
+	RECTANGLE,
+	HEXAGON,
+	LAST_SHAPE
+} shape_e;
+
+const char* shape_tostring[] = {"SQUARE","CIRCLE","TRIANGLE","RECTANGLE","HEXAGON"};
+
+struct ide{
+	shape_e shape;
+};
+
+typedef struct ide* ide_pt;
+
+#endif /* IDE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/common/include/kinematics.h
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/common/include/kinematics.h b/bundles/pubsub/examples/mp_pubsub/common/include/kinematics.h
new file mode 100644
index 0000000..5601509
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/common/include/kinematics.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.
+ */
+/*
+ * kinematics.h
+ *
+ *  \date       Nov 12, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef KINEMATICS_H_
+#define KINEMATICS_H_
+
+#define MIN_LAT	-90.0F
+#define MAX_LAT	 90.0F
+#define MIN_LON	-180.0F
+#define MAX_LON	 180.0F
+
+#define MIN_OCCUR 1
+#define MAX_OCCUR 5
+
+#define MSG_KINEMATICS_NAME	"kinematics" //Has to match the message name in the msg descriptor!
+
+struct position{
+	double lat;
+	double lon;
+};
+
+typedef struct position position_t;
+
+struct kinematics{
+	position_t position;
+	int occurrences;
+};
+
+typedef struct kinematics* kinematics_pt;
+
+
+#endif /* KINEMATICS_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor b/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor
new file mode 100644
index 0000000..7eb8c29
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor
@@ -0,0 +1,9 @@
+:header
+type=message
+name=ew
+version=1.0.0
+:annotations
+classname=org.example.Ew
+:types
+:message
+{Di area color}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_ide.descriptor
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_ide.descriptor b/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_ide.descriptor
new file mode 100644
index 0000000..f26286d
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_ide.descriptor
@@ -0,0 +1,9 @@
+:header
+type=message
+name=ide
+version=1.0.0
+:annotations
+classname=org.example.Ide
+:types
+:message
+{i shape}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_kinematics.descriptor
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_kinematics.descriptor b/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_kinematics.descriptor
new file mode 100644
index 0000000..447b645
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/msg_descriptors/msg_kinematics.descriptor
@@ -0,0 +1,10 @@
+:header
+type=message
+name=kinematics
+version=1.0.0
+:annotations
+classname=org.example.Kinematics
+:types
+position={DD lat long}
+:message
+{lposition;N position occurrences}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt b/bundles/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
new file mode 100644
index 0000000..653387e
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
@@ -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.
+
+add_celix_bundle(org.apache.celix.pubsub_publisher.MpPublisher
+    SYMBOLIC_NAME "apache_celix_pubsub_mp_publisher"
+    VERSION "1.0.0"
+    SOURCES 
+    	private/src/mp_pub_activator.c
+    	private/src/mp_publisher.c
+)
+target_link_libraries(org.apache.celix.pubsub_publisher.MpPublisher PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(org.apache.celix.pubsub_publisher.MpPublisher PRIVATE private/include)
+
+celix_bundle_files(org.apache.celix.pubsub_publisher.MpPublisher
+	${PROJECT_SOURCE_DIR}/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor
+	${PROJECT_SOURCE_DIR}/pubsub/examples/mp_pubsub/msg_descriptors/msg_ide.descriptor
+	${PROJECT_SOURCE_DIR}/pubsub/examples/mp_pubsub/msg_descriptors/msg_kinematics.descriptor
+	DESTINATION "META-INF/descriptors"
+)
+
+celix_bundle_files(org.apache.celix.pubsub_publisher.MpPublisher
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher
+    DESTINATION "META-INF/keys"
+)
+
+celix_bundle_files(org.apache.celix.pubsub_publisher.MpPublisher
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber/public
+    DESTINATION "META-INF/keys/subscriber"
+)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h b/bundles/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h
new file mode 100644
index 0000000..9c227fd
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h
@@ -0,0 +1,58 @@
+/**
+ *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.
+ */
+/*
+ * mp_publisher_private.h
+ *
+ *  \date       Sep 21, 2010
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef MP_PUBLISHER_PRIVATE_H_
+#define MP_PUBLISHER_PRIVATE_H_
+
+#include <celixbool.h>
+
+#include "pubsub/publisher.h"
+
+struct pubsub_sender {
+	array_list_pt trackers;
+	const char *ident;
+	long bundleId;
+};
+
+typedef struct pubsub_sender * pubsub_sender_pt;
+
+typedef struct send_thread_struct{
+	pubsub_publisher_pt service;
+	pubsub_sender_pt publisher;
+} *send_thread_struct_pt;
+
+pubsub_sender_pt publisher_create(array_list_pt trackers,const char* ident,long bundleId);
+
+void publisher_start(pubsub_sender_pt client);
+void publisher_stop(pubsub_sender_pt client);
+
+void publisher_destroy(pubsub_sender_pt client);
+
+celix_status_t publisher_publishSvcAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t publisher_publishSvcRemoved(void * handle, service_reference_pt reference, void * service);
+
+
+#endif /* MP_PUBLISHER_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c b/bundles/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
new file mode 100644
index 0000000..0b6041d
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
@@ -0,0 +1,144 @@
+/**
+ *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.
+ */
+/*
+ * mp_pub_activator.c
+ *
+ *  \date       Sep 21, 2010
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <sys/cdefs.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bundle_activator.h"
+#include "service_tracker.h"
+#include "constants.h"
+
+#include "mp_publisher_private.h"
+
+static const char * PUB_TOPICS[] = {
+		"multipart",
+		NULL
+};
+
+
+struct publisherActivator {
+	pubsub_sender_pt client;
+	array_list_pt trackerList;//List<service_tracker_pt>
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	struct publisherActivator * act = malloc(sizeof(*act));
+
+	const char* fwUUID = NULL;
+
+	bundleContext_getProperty(context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+	if(fwUUID == NULL){
+		printf("MP_PUBLISHER: Cannot retrieve fwUUID.\n");
+		status = CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+
+	if (status == CELIX_SUCCESS){
+		bundle_pt bundle = NULL;
+		long bundleId = 0;
+		bundleContext_getBundle(context,&bundle);
+		bundle_getBundleId(bundle,&bundleId);
+
+		arrayList_create(&(act->trackerList));
+		act->client = publisher_create(act->trackerList,fwUUID,bundleId);
+		*userData = act;
+	} else {
+		free(act);
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+
+	struct publisherActivator * act = (struct publisherActivator *) userData;
+
+	int i;
+
+	char filter[128];
+	for(i=0; PUB_TOPICS[i] != NULL; i++){
+		const char* topic = PUB_TOPICS[i];
+
+		bundle_pt bundle = NULL;
+		long bundleId = 0;
+		bundleContext_getBundle(context,&bundle);
+		bundle_getBundleId(bundle,&bundleId);
+
+		service_tracker_pt tracker = NULL;
+		memset(filter,0,128);
+
+		snprintf(filter, 128, "(&(%s=%s)(%s=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_PUBLISHER_SERVICE_NAME, PUBSUB_PUBLISHER_TOPIC,topic);
+
+		service_tracker_customizer_pt customizer = NULL;
+
+		serviceTrackerCustomizer_create(act->client,NULL,publisher_publishSvcAdded,NULL,publisher_publishSvcRemoved,&customizer);
+		serviceTracker_createWithFilter(context, filter, customizer, &tracker);
+
+		arrayList_add(act->trackerList,tracker);
+	}
+
+	publisher_start(act->client);
+
+	for(i=0;i<arrayList_size(act->trackerList);i++){
+		service_tracker_pt tracker = arrayList_get(act->trackerList,i);
+		serviceTracker_open(tracker);
+	}
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt __attribute__((unused)) context) {
+	struct publisherActivator * act = (struct publisherActivator *) userData;
+	int i;
+
+	for(i=0;i<arrayList_size(act->trackerList);i++){
+		service_tracker_pt tracker = arrayList_get(act->trackerList,i);
+		serviceTracker_close(tracker);
+	}
+
+	publisher_stop(act->client);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt  __attribute__((unused)) context) {
+	struct publisherActivator * act = (struct publisherActivator *) userData;
+	int i;
+
+	for(i=0;i<arrayList_size(act->trackerList);i++){
+		service_tracker_pt tracker = arrayList_get(act->trackerList,i);
+		serviceTracker_destroy(tracker);
+	}
+
+	publisher_destroy(act->client);
+	arrayList_destroy(act->trackerList);
+
+	free(act);
+
+	return CELIX_SUCCESS;
+}