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:52:49 UTC

[41/60] [abbrv] [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/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c b/bundles/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
new file mode 100644
index 0000000..f47be29
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
@@ -0,0 +1,160 @@
+/**
+ *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.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 <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include "service_tracker.h"
+#include "celix_threads.h"
+
+#include "ew.h"
+#include "ide.h"
+#include "kinematics.h"
+#include "mp_publisher_private.h"
+
+
+static bool stop=false;
+static celix_thread_t tid;
+
+static double randDouble(double min, double max){
+	double ret = min + (((double)random()) / (((double)RAND_MAX)/(max-min))) ;
+	return ret;
+}
+
+static unsigned int randInt(unsigned int min, unsigned int max){
+	double scaled = ((double)random())/((double)RAND_MAX);
+	return (max - min +1)*scaled + min;
+}
+
+static void* send_thread(void* arg){
+
+	send_thread_struct_pt st_struct = (send_thread_struct_pt)arg;
+
+	pubsub_publisher_pt publish_svc = (pubsub_publisher_pt)st_struct->service;
+
+	unsigned int kin_msg_id = 0;
+	unsigned int ide_msg_id = 0;
+	unsigned int ew_msg_id = 0;
+
+	if( publish_svc->localMsgTypeIdForMsgType(publish_svc->handle,(const char*)MSG_KINEMATICS_NAME,&kin_msg_id) != 0 ){
+		printf("MP_PUBLISHER: Cannot retrieve msgId for message '%s'\n",MSG_KINEMATICS_NAME);
+		return NULL;
+	}
+
+	if( publish_svc->localMsgTypeIdForMsgType(publish_svc->handle,(const char*)MSG_IDE_NAME,&ide_msg_id) != 0 ){
+		printf("MP_PUBLISHER: Cannot retrieve msgId for message '%s'\n",MSG_IDE_NAME);
+		return NULL;
+	}
+
+	if( publish_svc->localMsgTypeIdForMsgType(publish_svc->handle,(const char*)MSG_EW_NAME,&ew_msg_id) != 0 ){
+		printf("MP_PUBLISHER: Cannot retrieve msgId for message '%s'\n",MSG_EW_NAME);
+		return NULL;
+	}
+
+	kinematics_pt kin_data = calloc(1,sizeof(*kin_data));
+	ide_pt ide_data = calloc(1,sizeof(*ide_data));
+	ew_data_pt ew_data = calloc(1,sizeof(*ew_data));
+
+	unsigned int counter = 1;
+
+	while(stop==false){
+		kin_data->position.lat = randDouble(MIN_LAT,MAX_LAT);
+		kin_data->position.lon = randDouble(MIN_LON,MAX_LON);
+		kin_data->occurrences = randInt(MIN_OCCUR,MAX_OCCUR);
+		publish_svc->sendMultipart(publish_svc->handle,kin_msg_id,kin_data, PUBSUB_PUBLISHER_FIRST_MSG);
+		printf("Track#%u kin_data: pos=[%f, %f] occurrences=%d\n",counter,kin_data->position.lat,kin_data->position.lon, kin_data->occurrences);
+
+		ide_data->shape = (shape_e)randInt(0,LAST_SHAPE-1);
+		publish_svc->sendMultipart(publish_svc->handle,ide_msg_id,ide_data, PUBSUB_PUBLISHER_PART_MSG);
+		printf("Track#%u ide_data: shape=%s\n",counter,shape_tostring[(int)ide_data->shape]);
+
+		ew_data->area = randDouble(MIN_AREA,MAX_AREA);
+		ew_data->color = (color_e)randInt(0,LAST_COLOR-1);
+		publish_svc->sendMultipart(publish_svc->handle,ew_msg_id,ew_data, PUBSUB_PUBLISHER_LAST_MSG);
+		printf("Track#%u ew_data: area=%f color=%s\n",counter,ew_data->area,color_tostring[(int)ew_data->color]);
+
+		printf("\n");
+		sleep(2);
+		counter++;
+	}
+
+	free(ew_data);
+	free(ide_data);
+	free(kin_data);
+	free(st_struct);
+
+	return NULL;
+
+}
+
+pubsub_sender_pt publisher_create(array_list_pt trackers,const char* ident,long bundleId) {
+	pubsub_sender_pt publisher = malloc(sizeof(*publisher));
+
+	publisher->trackers = trackers;
+	publisher->ident = ident;
+	publisher->bundleId = bundleId;
+
+	return publisher;
+}
+
+void publisher_start(pubsub_sender_pt client) {
+	printf("MP_PUBLISHER: starting up...\n");
+}
+
+void publisher_stop(pubsub_sender_pt client) {
+	printf("MP_PUBLISHER: stopping...\n");
+}
+
+void publisher_destroy(pubsub_sender_pt client) {
+	client->trackers = NULL;
+	client->ident = NULL;
+	free(client);
+}
+
+celix_status_t publisher_publishSvcAdded(void * handle, service_reference_pt reference, void * service){
+	pubsub_publisher_pt publish_svc = (pubsub_publisher_pt)service;
+	pubsub_sender_pt manager = (pubsub_sender_pt)handle;
+
+	printf("MP_PUBLISHER: new publish service exported (%s).\n",manager->ident);
+
+	send_thread_struct_pt data = calloc(1,sizeof(struct send_thread_struct));
+	data->service = publish_svc;
+	data->publisher = manager;
+
+	celixThread_create(&tid,NULL,send_thread,(void*)data);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t publisher_publishSvcRemoved(void * handle, service_reference_pt reference, void * service){
+	//publish_service_pt publish_svc = (publish_service_pt)service;
+	pubsub_sender_pt manager = (pubsub_sender_pt)handle;
+	printf("MP_PUBLISHER: publish service unexported (%s)!\n",manager->ident);
+	stop=true;
+	celixThread_join(tid,NULL);
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt b/bundles/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
new file mode 100644
index 0000000..1185ec5
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/subscriber/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_subscriber.MpSubscriber
+    SYMBOLIC_NAME "apache_celix_pubsub_mp_subscriber"
+    VERSION "1.0.0"
+    SOURCES 
+		private/src/mp_sub_activator.c
+		private/src/mp_subscriber.c
+)
+target_link_libraries(org.apache.celix.pubsub_subscriber.MpSubscriber PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(org.apache.celix.pubsub_subscriber.MpSubscriber PRIVATE private/include)
+
+celix_bundle_files( org.apache.celix.pubsub_subscriber.MpSubscriber
+    ${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_subscriber.MpSubscriber
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber
+    DESTINATION "META-INF/keys"
+)
+
+celix_bundle_files(org.apache.celix.pubsub_subscriber.MpSubscriber
+	${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher/public
+    DESTINATION "META-INF/keys/publisher"
+)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h b/bundles/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h
new file mode 100644
index 0000000..2d582b3
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.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.
+ */
+/*
+ * mp_subscriber_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 PUBSUB_SUBSCRIBER_PRIVATE_H_
+#define PUBSUB_SUBSCRIBER_PRIVATE_H_
+
+
+#include <string.h>
+
+#include "celixbool.h"
+
+#include "pubsub/subscriber.h"
+
+struct pubsub_receiver {
+	char * name;
+};
+
+typedef struct pubsub_receiver* pubsub_receiver_pt;
+
+pubsub_receiver_pt subscriber_create(char* topics);
+void subscriber_start(pubsub_receiver_pt client);
+void subscriber_stop(pubsub_receiver_pt client);
+void subscriber_destroy(pubsub_receiver_pt client);
+
+int pubsub_subscriber_recv(void* handle, const char* msgType, unsigned int msgTypeId, void* msg,pubsub_multipart_callbacks_t *callbacks, bool* release);
+
+#endif /* PUBSUB_SUBSCRIBER_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c b/bundles/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
new file mode 100644
index 0000000..591a395
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
@@ -0,0 +1,108 @@
+/**
+ *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_sub_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 <stdlib.h>
+
+#include "pubsub/subscriber.h"
+#include "bundle_activator.h"
+
+#include "mp_subscriber_private.h"
+
+#define SUB_NAME "multipart"
+static const char * SUB_TOPICS[] = {
+		"multipart",
+		NULL
+};
+
+struct subscriberActivator {
+	array_list_pt registrationList; //List<service_registration_pt>
+	pubsub_subscriber_t* subsvc;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	struct subscriberActivator * act = calloc(1,sizeof(struct subscriberActivator));
+	*userData = act;
+	arrayList_create(&(act->registrationList));
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	struct subscriberActivator * act = (struct subscriberActivator *) userData;
+
+
+	pubsub_subscriber_pt subsvc = calloc(1,sizeof(*subsvc));
+	pubsub_receiver_pt sub = subscriber_create(SUB_NAME);
+	subsvc->handle = sub;
+	subsvc->receive = pubsub_subscriber_recv;
+
+	act->subsvc = subsvc;
+
+	int i;
+	for(i=0; SUB_TOPICS[i] != NULL; i++){
+		const char* topic = SUB_TOPICS[i];
+
+		properties_pt props = properties_create();
+		properties_set(props, PUBSUB_SUBSCRIBER_TOPIC,topic);
+		service_registration_pt reg = NULL;
+		bundleContext_registerService(context, PUBSUB_SUBSCRIBER_SERVICE_NAME, subsvc, props, &reg);
+		arrayList_add(act->registrationList,reg);
+	}
+
+	subscriber_start((pubsub_receiver_pt)act->subsvc->handle);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	struct subscriberActivator * act = (struct subscriberActivator *) userData;
+
+	int i;
+	for(i=0; i<arrayList_size(act->registrationList);i++){
+		service_registration_pt reg = arrayList_get(act->registrationList,i);
+		serviceRegistration_unregister(reg);
+
+	}
+
+	subscriber_stop((pubsub_receiver_pt)act->subsvc->handle);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+
+	struct subscriberActivator * act = (struct subscriberActivator *) userData;
+
+	act->subsvc->receive = NULL;
+	subscriber_destroy((pubsub_receiver_pt)act->subsvc->handle);
+	act->subsvc->handle = NULL;
+	free(act->subsvc);
+	act->subsvc = NULL;
+
+	arrayList_destroy(act->registrationList);
+	free(act);
+
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/mp_pubsub/subscriber/private/src/mp_subscriber.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/mp_pubsub/subscriber/private/src/mp_subscriber.c b/bundles/pubsub/examples/mp_pubsub/subscriber/private/src/mp_subscriber.c
new file mode 100644
index 0000000..a5ad03a
--- /dev/null
+++ b/bundles/pubsub/examples/mp_pubsub/subscriber/private/src/mp_subscriber.c
@@ -0,0 +1,119 @@
+/**
+ *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_subscriber.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 <stdlib.h>
+#include <stdio.h>
+
+#include "ew.h"
+#include "ide.h"
+#include "kinematics.h"
+#include "mp_subscriber_private.h"
+
+pubsub_receiver_pt subscriber_create(char* topics) {
+	pubsub_receiver_pt sub = calloc(1,sizeof(*sub));
+	sub->name = strdup(topics);
+	return sub;
+}
+
+
+void subscriber_start(pubsub_receiver_pt subscriber){
+	printf("MP_SUBSCRIBER: starting up...\n");
+}
+
+void subscriber_stop(pubsub_receiver_pt subscriber){
+	printf("MP_SUBSCRIBER: stopping...\n");
+}
+
+void subscriber_destroy(pubsub_receiver_pt subscriber){
+	if(subscriber->name!=NULL){
+		free(subscriber->name);
+	}
+	subscriber->name=NULL;
+	free(subscriber);
+}
+
+int pubsub_subscriber_recv(void* handle, const char* msgType, unsigned int msgTypeId, void* msg,pubsub_multipart_callbacks_t *callbacks, bool* release){
+
+	unsigned int kin_msg_id = 0;
+	unsigned int ide_msg_id = 0;
+	unsigned int ew_msg_id = 0;
+
+	if( callbacks->localMsgTypeIdForMsgType(callbacks->handle,(const char*)MSG_KINEMATICS_NAME,&kin_msg_id) != 0 ){
+		printf("MP_SUBSCRIBER: Cannot retrieve msgId for message '%s'\n",MSG_KINEMATICS_NAME);
+		return -1;
+	}
+
+	if( callbacks->localMsgTypeIdForMsgType(callbacks->handle,(const char*)MSG_IDE_NAME,&ide_msg_id) != 0 ){
+		printf("MP_SUBSCRIBER: Cannot retrieve msgId for message '%s'\n",MSG_IDE_NAME);
+		return -1;
+	}
+
+	if( callbacks->localMsgTypeIdForMsgType(callbacks->handle,(const char*)MSG_EW_NAME,&ew_msg_id) != 0 ){
+		printf("MP_SUBSCRIBER: Cannot retrieve msgId for message '%s'\n",MSG_EW_NAME);
+		return -1;
+	}
+
+	if(msgTypeId!=kin_msg_id){
+		printf("MP_SUBSCRIBER: Multipart Message started with wrong message (expected %u, got %u)\n",msgTypeId,kin_msg_id);
+		return -1;
+	}
+
+	kinematics_pt kin_data = (kinematics_pt)msg;
+
+	void* ide_msg = NULL;
+	callbacks->getMultipart(callbacks->handle,ide_msg_id,false,&ide_msg);
+
+	void* ew_msg = NULL;
+	callbacks->getMultipart(callbacks->handle,ew_msg_id,false,&ew_msg);
+
+	if(kin_data==NULL){
+		printf("MP_SUBSCRIBER: Unexpected NULL data for message '%s'\n",MSG_KINEMATICS_NAME);
+	}
+	else{
+		printf("kin_data: pos=[%f, %f] occurrences=%d\n",kin_data->position.lat,kin_data->position.lon, kin_data->occurrences);
+	}
+
+	if(ide_msg==NULL){
+		printf("MP_SUBSCRIBER: Unexpected NULL data for message '%s'\n",MSG_IDE_NAME);
+	}
+	else{
+		ide_pt ide_data = (ide_pt)ide_msg;
+		printf("ide_data: shape=%s\n",shape_tostring[(int)ide_data->shape]);
+	}
+
+	if(ew_msg==NULL){
+		printf("MP_SUBSCRIBER: Unexpected NULL data for message '%s'\n",MSG_EW_NAME);
+	}
+	else{
+		ew_data_pt ew_data = (ew_data_pt)ew_msg;
+		printf("ew_data: area=%f color=%s\n",ew_data->area,color_tostring[(int)ew_data->color]);
+	}
+
+	printf("\n");
+
+	return 0;
+
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/CMakeLists.txt b/bundles/pubsub/examples/pubsub/CMakeLists.txt
new file mode 100644
index 0000000..73b3e52
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/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.
+
+include_directories("common/include")
+
+add_subdirectory(publisher)
+add_subdirectory(publisher2)
+add_subdirectory(subscriber)
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/common/include/poi.h
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/common/include/poi.h b/bundles/pubsub/examples/pubsub/common/include/poi.h
new file mode 100644
index 0000000..7bb077e
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/common/include/poi.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.
+ */
+/*
+ * poi.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 POI_H_
+#define POI_H_
+
+#define MIN_LAT	-90.0F
+#define MAX_LAT	 90.0F
+#define MIN_LON	-180.0F
+#define MAX_LON	 180.0F
+
+#define MSG_POI_NAME	"poi" //Has to match the message name in the msg descriptor!
+
+struct poi{
+	double lat;
+	double lon;
+};
+
+typedef struct poi1 poi1_t;
+
+struct location{
+	struct poi position;
+	char* name;
+	char* description;
+	char* extra;
+	char* data;
+};
+
+typedef struct location* location_t;
+
+
+#endif /* POI_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor b/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
new file mode 100644
index 0000000..e547b62
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
@@ -0,0 +1,10 @@
+:header
+type=message
+name=poi1
+version=1.0.0
+:annotations
+classname=org.example.PointOfInterest
+:types
+location={DD lat long}
+:message
+{llocation;tttt location name description extra data}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor b/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
new file mode 100644
index 0000000..0c369b5
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
@@ -0,0 +1,10 @@
+:header
+type=message
+name=poi2
+version=1.0.0
+:annotations
+classname=org.example.PointOfInterest
+:types
+location={DD lat long}
+:message
+{llocation;tttt location name description extra data}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties b/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties
new file mode 100644
index 0000000..16a1962
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties
@@ -0,0 +1,35 @@
+# 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.
+
+#
+# included in the bundle at location META-INF/topics/[pub|sub]/poi1.properties
+#
+
+#topic info
+topic.name=poi1
+topic.id=poi1
+
+#Interface info
+interface.name=org.example.unknown
+interface.version=1.0.0
+interface.messages=poi1 poi2
+
+# Version info
+interface.message.consumer.range@poi1=[0.0.0,1.0.0)
+interface.message.provider.version@poi1=0.0.0
+interface.message.consumer.range@poi2=[0.0.0,1.0.0)
+interface.message.provider.version@poi2=0.0.0

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties b/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties
new file mode 100644
index 0000000..739075c
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties
@@ -0,0 +1,35 @@
+# 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.
+
+#
+# included in the bundle at location META-INF/topics/[pub|sub]/poi2.properties
+#
+
+#topic info
+topic.name=poi2
+topic.id=poi2
+
+#Interface info
+interface.name=org.example.unknown
+interface.version=1.0.0
+interface.messages=poi1 poi2
+
+# Version info
+interface.message.consumer.range@poi1=[0.0.0,1.0.0)
+interface.message.provider.version@poi1=0.0.0
+interface.message.consumer.range@poi2=[0.0.0,1.0.0)
+interface.message.provider.version@poi2=0.0.0

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/publisher/CMakeLists.txt b/bundles/pubsub/examples/pubsub/publisher/CMakeLists.txt
new file mode 100644
index 0000000..176a57e
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/publisher/CMakeLists.txt
@@ -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.
+
+add_celix_bundle(celix_pubsub_poi_publisher
+    SYMBOLIC_NAME "apache_celix_pubsub_poi_publisher"
+    VERSION "1.0.0"
+    SOURCES 
+    	private/src/ps_pub_activator.c
+    	private/src/pubsub_publisher.c
+)
+
+target_link_libraries(celix_pubsub_poi_publisher PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(celix_pubsub_poi_publisher PRIVATE private/include)
+
+celix_bundle_files(celix_pubsub_poi_publisher
+		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
+		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
+    DESTINATION "META-INF/descriptors"
+)
+
+celix_bundle_files(celix_pubsub_poi_publisher
+		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi1.properties
+		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi2.properties
+    DESTINATION "META-INF/topics/pub"
+)
+
+celix_bundle_files(celix_pubsub_poi_publisher
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher
+    DESTINATION "META-INF/keys"
+)
+
+celix_bundle_files(celix_pubsub_poi_publisher
+		${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/pubsub/publisher/private/include/pubsub_publisher_private.h
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h b/bundles/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h
new file mode 100644
index 0000000..56ec678
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.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.
+ */
+/*
+ * pubsub_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 PUBSUB_PUBLISHER_PRIVATE_H_
+#define PUBSUB_PUBLISHER_PRIVATE_H_
+
+#include <celixbool.h>
+#include <pthread.h>
+#include "pubsub/publisher.h"
+
+struct pubsub_sender {
+	array_list_pt trackers;
+	const char *ident;
+	hash_map_pt tid_map; //service -> tid
+	long bundleId;
+};
+
+typedef struct pubsub_sender * pubsub_sender_pt;
+
+typedef struct send_thread_struct{
+	pubsub_publisher_pt service;
+	pubsub_sender_pt publisher;
+	const char *topic;
+} *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 /* PUBSUB_PUBLISHER_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c b/bundles/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
new file mode 100644
index 0000000..0da3ffc
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
@@ -0,0 +1,147 @@
+/**
+ *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_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 "pubsub/publisher.h"
+#include "pubsub_publisher_private.h"
+
+static const char * PUB_TOPICS[] = {
+		"poi1",
+		"poi2",
+		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) {
+
+	const char* fwUUID = NULL;
+
+	bundleContext_getProperty(context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+	if(fwUUID==NULL){
+		printf("PUBLISHER: Cannot retrieve fwUUID.\n");
+		return CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+
+	struct publisherActivator * act = malloc(sizeof(*act));
+
+	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;
+
+	return CELIX_SUCCESS;
+}
+
+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);
+#ifdef USE_SCOPE
+			char *scope;
+			asprintf(&scope, "my_scope_%d", i);
+			snprintf(filter, 128, "(&(&(%s=%s)(%s=%s))(%s=%s))",
+					(char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_PUBLISHER_SERVICE_NAME,
+					PUBSUB_PUBLISHER_TOPIC, topic,
+					PUBLISHER_SCOPE, scope);
+			free(scope);
+#else
+		snprintf(filter, 128, "(&(%s=%s)(%s=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_PUBLISHER_SERVICE_NAME, PUBSUB_PUBLISHER_TOPIC, topic);
+#endif
+		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);
+	printf("PUBLISHER: bundleActivator_destroy\n");
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c b/bundles/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c
new file mode 100644
index 0000000..9a7aedc
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c
@@ -0,0 +1,172 @@
+/**
+ *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_publisher.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 <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include "service_tracker.h"
+#include "celix_threads.h"
+
+#include "poi.h"
+
+#include "pubsub_publisher_private.h"
+
+static bool stop=false;
+
+static double randCoordinate(double min, double max){
+
+	double ret = min + (((double)random()) / (((double)RAND_MAX)/(max-min))) ;
+
+	return ret;
+
+}
+
+static void* send_thread(void* arg){
+
+	send_thread_struct_pt st_struct = (send_thread_struct_pt)arg;
+
+	pubsub_publisher_pt publish_svc = (pubsub_publisher_pt)st_struct->service;
+	pubsub_sender_pt publisher = (pubsub_sender_pt)st_struct->publisher;
+
+	char fwUUID[9];
+	memset(fwUUID,0,9);
+	memcpy(fwUUID,publisher->ident,8);
+
+	//poi_t point = calloc(1,sizeof(*point));
+	location_t place = calloc(1,sizeof(*place));
+
+	char* desc = calloc(64,sizeof(char));
+	snprintf(desc,64,"fw-%s [TID=%lu]", fwUUID, (unsigned long)pthread_self());
+
+	char* name = calloc(64,sizeof(char));
+	snprintf(name,64,"Bundle#%ld",publisher->bundleId);
+
+	place->name = name;
+	place->description = desc;
+	place->extra = "DONT PANIC";
+	printf("TOPIC : %s\n",st_struct->topic);
+	unsigned int msgId = 0;
+	if( publish_svc->localMsgTypeIdForMsgType(publish_svc->handle,st_struct->topic,&msgId) == 0 ){
+
+		while(stop==false){
+			place->position.lat = randCoordinate(MIN_LAT,MAX_LAT);
+			place->position.lon = randCoordinate(MIN_LON,MAX_LON);
+			int nr_char = (int)randCoordinate(5,100000);
+			place->data = calloc(nr_char, 1);
+			for(int i = 0; i < (nr_char-1); i++) {
+				place->data[i] = i%10 + '0';
+			}
+			if(publish_svc->send) {
+				if(publish_svc->send(publish_svc->handle,msgId,place)==0){
+					printf("Sent %s [%f, %f] (%s, %s) data len = %d\n",st_struct->topic, place->position.lat, place->position.lon,place->name,place->description, nr_char);
+				}
+			} else {
+				printf("No send for %s\n", st_struct->topic);
+			}
+
+			free(place->data);
+			sleep(2);
+		}
+	}
+	else{
+		printf("PUBLISHER: Cannot retrieve msgId for message '%s'\n",MSG_POI_NAME);
+	}
+
+	free(place->description);
+	free(place->name);
+	free(place);
+
+	free(st_struct);
+
+
+	return NULL;
+
+}
+
+pubsub_sender_pt publisher_create(array_list_pt trackers,const char* ident,long bundleId) {
+	pubsub_sender_pt publisher = malloc(sizeof(*publisher));
+
+	publisher->trackers = trackers;
+	publisher->ident = ident;
+	publisher->bundleId = bundleId;
+	publisher->tid_map = hashMap_create(NULL, NULL, NULL, NULL);
+
+	return publisher;
+}
+
+void publisher_start(pubsub_sender_pt client) {
+	printf("PUBLISHER: starting up...\n");
+}
+
+void publisher_stop(pubsub_sender_pt client) {
+	printf("PUBLISHER: stopping...\n");
+}
+
+void publisher_destroy(pubsub_sender_pt client) {
+	hashMap_destroy(client->tid_map, false, false);
+	client->trackers = NULL;
+	client->ident = NULL;
+	free(client);
+}
+
+celix_status_t publisher_publishSvcAdded(void * handle, service_reference_pt reference, void * service){
+	pubsub_publisher_pt publish_svc = (pubsub_publisher_pt)service;
+	pubsub_sender_pt manager = (pubsub_sender_pt)handle;
+
+	printf("PUBLISHER: new publish service exported (%s).\n",manager->ident);
+
+	send_thread_struct_pt data = calloc(1,sizeof(struct send_thread_struct));
+	const char *value = NULL;
+	serviceReference_getProperty(reference, PUBSUB_PUBLISHER_TOPIC, &value);
+	data->service = publish_svc;
+	data->publisher = manager;
+	data->topic = value;
+	celix_thread_t *tid = malloc(sizeof(*tid));
+	stop=false;
+	celixThread_create(tid,NULL,send_thread,(void*)data);
+	hashMap_put(manager->tid_map, publish_svc, tid);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t publisher_publishSvcRemoved(void * handle, service_reference_pt reference, void * service){
+	pubsub_sender_pt manager = (pubsub_sender_pt)handle;
+	celix_thread_t *tid = hashMap_get(manager->tid_map, service);
+
+#if defined(__APPLE__) && defined(__MACH__)
+	uint64_t threadid;
+	pthread_threadid_np(tid->thread, &threadid);
+	printf("PUBLISHER: publish service unexporting (%s) %llu!\n",manager->ident, threadid);
+#else
+	printf("PUBLISHER: publish service unexporting (%s) %li!\n",manager->ident, tid->thread);
+#endif
+
+	stop=true;
+	celixThread_join(*tid,NULL);
+	free(tid);
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/publisher2/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/publisher2/CMakeLists.txt b/bundles/pubsub/examples/pubsub/publisher2/CMakeLists.txt
new file mode 100644
index 0000000..30d86ee
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/publisher2/CMakeLists.txt
@@ -0,0 +1,51 @@
+# 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(celix_pubsub_poi_publisher2
+    SYMBOLIC_NAME "apache_celix_pubsub_poi_publisher2"
+    VERSION "1.0.0"
+    SOURCES 
+    	../publisher/private/src/ps_pub_activator.c
+    	../publisher/private/src/pubsub_publisher.c
+)
+target_link_libraries(celix_pubsub_poi_publisher2 PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(celix_pubsub_poi_publisher2 PRIVATE ../publisher/private/include)
+
+
+celix_bundle_files(celix_pubsub_poi_publisher2
+	${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
+	${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
+    DESTINATION "META-INF/descriptors"
+)
+
+celix_bundle_files(celix_pubsub_poi_publisher2
+		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi1.properties
+		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi2.properties
+    DESTINATION "META-INF/topics/pub"
+)
+
+celix_bundle_files(celix_pubsub_poi_publisher2
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher
+    DESTINATION "META-INF/keys"
+)
+
+celix_bundle_files(celix_pubsub_poi_publisher2
+	${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber/public
+    DESTINATION "META-INF/keys/subscriber"
+)
+
+target_link_libraries(celix_pubsub_poi_publisher2 PRIVATE Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/subscriber/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/subscriber/CMakeLists.txt b/bundles/pubsub/examples/pubsub/subscriber/CMakeLists.txt
new file mode 100644
index 0000000..0eb13ff
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/subscriber/CMakeLists.txt
@@ -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.
+
+add_celix_bundle(celix_pubsub_poi_subscriber
+    SYMBOLIC_NAME "apache_celix_pubsub_poi_subscriber" 
+    VERSION "1.0.0"
+    SOURCES 
+    	private/src/ps_sub_activator.c
+		private/src/pubsub_subscriber.c
+)
+
+target_link_libraries(celix_pubsub_poi_subscriber PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(celix_pubsub_poi_subscriber PRIVATE private/include)
+
+
+celix_bundle_files(celix_pubsub_poi_subscriber
+	    ${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
+	    ${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
+    DESTINATION "META-INF/descriptors"
+)
+
+celix_bundle_files(celix_pubsub_poi_subscriber
+		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi1.properties
+		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi2.properties
+    DESTINATION "META-INF/topics/sub"
+)
+
+celix_bundle_files(celix_pubsub_poi_subscriber
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber
+    DESTINATION "META-INF/keys"
+)
+
+celix_bundle_files(celix_pubsub_poi_subscriber
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher/public
+    DESTINATION "META-INF/keys/publisher"
+)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h b/bundles/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h
new file mode 100644
index 0000000..00ca9b4
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h
@@ -0,0 +1,51 @@
+/**
+ *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_subscriber_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 PUBSUB_SUBSCRIBER_PRIVATE_H_
+#define PUBSUB_SUBSCRIBER_PRIVATE_H_
+
+
+#include <string.h>
+
+#include "celixbool.h"
+
+#include "pubsub/subscriber.h"
+
+struct pubsub_receiver {
+	char * name;
+};
+
+typedef struct pubsub_receiver* pubsub_receiver_pt;
+
+pubsub_receiver_pt subscriber_create(char* topics);
+void subscriber_start(pubsub_receiver_pt client);
+void subscriber_stop(pubsub_receiver_pt client);
+void subscriber_destroy(pubsub_receiver_pt client);
+
+int pubsub_subscriber_recv(void* handle, const char* msgType, unsigned int msgTypeId, void* msg,pubsub_multipart_callbacks_t *callbacks, bool* release);
+
+
+#endif /* PUBSUB_SUBSCRIBER_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c b/bundles/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c
new file mode 100644
index 0000000..5f3b283
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c
@@ -0,0 +1,114 @@
+/**
+ *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_sub_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 <stdlib.h>
+#include <pubsub/subscriber.h>
+
+#include "bundle_activator.h"
+
+#include "pubsub_subscriber_private.h"
+
+#define SUB_NAME "poi1;poi2"
+static const char * SUB_TOPICS[] = {
+		"poi1",
+		"poi2",
+		NULL
+};
+
+struct subscriberActivator {
+	array_list_pt registrationList; //List<service_registration_pt>
+	pubsub_subscriber_pt subsvc;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	struct subscriberActivator * act = calloc(1,sizeof(struct subscriberActivator));
+	*userData = act;
+	arrayList_create(&(act->registrationList));
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	struct subscriberActivator * act = (struct subscriberActivator *) userData;
+
+
+	pubsub_subscriber_pt subsvc = calloc(1,sizeof(*subsvc));
+	pubsub_receiver_pt sub = subscriber_create(SUB_NAME);
+	subsvc->handle = sub;
+	subsvc->receive = pubsub_subscriber_recv;
+
+	act->subsvc = subsvc;
+
+	int i;
+	for(i=0; SUB_TOPICS[i] != NULL ;i++){
+		const char* topic = SUB_TOPICS[i];
+		properties_pt props = properties_create();
+		properties_set(props, PUBSUB_SUBSCRIBER_TOPIC,topic);
+#ifdef USE_SCOPE
+			char *scope;
+			asprintf(&scope, "my_scope_%d", i);
+			properties_set(props,SUBSCRIBER_SCOPE,scope);
+			free(scope);
+#endif
+		service_registration_pt reg = NULL;
+		bundleContext_registerService(context, PUBSUB_SUBSCRIBER_SERVICE_NAME, subsvc, props, &reg);
+		arrayList_add(act->registrationList,reg);
+	}
+
+	subscriber_start((pubsub_receiver_pt)act->subsvc->handle);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	struct subscriberActivator * act = (struct subscriberActivator *) userData;
+
+	int i;
+	for(i=0; i<arrayList_size(act->registrationList);i++){
+		service_registration_pt reg = arrayList_get(act->registrationList,i);
+		serviceRegistration_unregister(reg);
+
+	}
+
+	subscriber_stop((pubsub_receiver_pt)act->subsvc->handle);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+
+	struct subscriberActivator * act = (struct subscriberActivator *) userData;
+
+	act->subsvc->receive = NULL;
+	subscriber_destroy((pubsub_receiver_pt)act->subsvc->handle);
+	act->subsvc->handle = NULL;
+	free(act->subsvc);
+	act->subsvc = NULL;
+
+	arrayList_destroy(act->registrationList);
+	free(act);
+
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c b/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c
new file mode 100644
index 0000000..a137253
--- /dev/null
+++ b/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c
@@ -0,0 +1,64 @@
+/**
+ *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_subscriber.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 <stdlib.h>
+#include <stdio.h>
+
+#include "poi.h"
+#include "pubsub_subscriber_private.h"
+
+pubsub_receiver_pt subscriber_create(char* topics) {
+	pubsub_receiver_pt sub = calloc(1,sizeof(*sub));
+	sub->name = strdup(topics);
+	return sub;
+}
+
+
+void subscriber_start(pubsub_receiver_pt subscriber){
+	printf("Subscriber started...\n");
+}
+
+void subscriber_stop(pubsub_receiver_pt subscriber){
+	printf("Subscriber stopped...\n");
+}
+
+void subscriber_destroy(pubsub_receiver_pt subscriber){
+	if(subscriber->name!=NULL){
+		free(subscriber->name);
+	}
+	subscriber->name=NULL;
+	free(subscriber);
+}
+
+int pubsub_subscriber_recv(void* handle, const char* msgType, unsigned int msgTypeId, void* msg,pubsub_multipart_callbacks_t *callbacks, bool* release){
+
+	location_t place = (location_t)msg;
+	int nrchars = 25;
+	printf("Recv (%s): [%f, %f] (%s, %s) data_len = %ld data =%*.*s\n",msgType, place->position.lat, place->position.lon,place->name,place->description, strlen(place->data) + 1, nrchars, nrchars, place->data);
+
+	return 0;
+
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/keygen/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/keygen/CMakeLists.txt b/bundles/pubsub/keygen/CMakeLists.txt
new file mode 100644
index 0000000..bc42173
--- /dev/null
+++ b/bundles/pubsub/keygen/CMakeLists.txt
@@ -0,0 +1,34 @@
+# 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.
+
+if (BUILD_ZMQ_SECURITY)
+
+	find_package(ZMQ REQUIRED)
+	find_package(CZMQ REQUIRED)
+	find_package(OpenSSL 1.1.0 REQUIRED)
+	
+	include_directories("${ZMQ_INCLUDE_DIR}")
+	include_directories("${CZMQ_INCLUDE_DIR}")
+	include_directories("${OPENSSL_INCLUDE_DIR}")
+	
+	add_executable(makecert makecert.c)
+	target_link_libraries(makecert ${CZMQ_LIBRARIES})
+	
+	add_executable(ed_file ed_file.c)
+	target_link_libraries(ed_file ${ZMQ_LIBRARIES} ${CZMQ_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARY})
+
+endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/keygen/ed_file.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/keygen/ed_file.c b/bundles/pubsub/keygen/ed_file.c
new file mode 100644
index 0000000..a0fc7e2
--- /dev/null
+++ b/bundles/pubsub/keygen/ed_file.c
@@ -0,0 +1,309 @@
+/**
+ *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.
+ */
+/*
+ * ed_file.c
+ *
+ *  \date       Dec 2, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <czmq.h>
+#include <openssl/evp.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+
+#define MAX_KEY_FILE_LENGTH 256
+#define MAX_LINE_LENGTH 64
+#define AES_KEY_LENGTH 32
+#define AES_IV_LENGTH 16
+
+#define KEY_TO_GET "aes_key"
+#define IV_TO_GET "aes_iv"
+
+int generate_sha256_hash(char* text, unsigned char* digest);
+int encrypt_aes(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext);
+int decrypt_aes(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext);
+
+static char* read_keys_file_content(const char *filePath);
+static void parse_key_lines(char *keysBuffer, char **key, char **iv);
+static void parse_key_line(char *line, char **key, char **iv);
+
+int main(int argc, const char* argv[])
+{
+	if (argc < 4){
+		printf("Usage: %s <key_file> <input_file> <output_file> [options]\n", argv[0]);
+		printf("Default behavior: encrypting a file\n");
+		printf("Options:\n");
+		printf("\t-d\tSpecify to decrypt a file\n");
+		printf("\n");
+		return EXIT_FAILURE;
+	}
+
+	int rc = 0;
+
+	const char* keys_file_path = argv[1];
+	const char* input_file_path = argv[2];
+	const char* output_file_path = argv[3];
+
+	bool decryptParam = false;
+	if (argc > 4 && strcmp(argv[4], "-d") == 0){
+		decryptParam = true;
+	}
+
+	if (!zsys_file_exists(keys_file_path)){
+		printf("Keys file '%s' doesn't exist!\n", keys_file_path);
+		return EXIT_FAILURE;
+	}
+
+	if (!zsys_file_exists(input_file_path)){
+		printf("Input file does not exist!\n");
+		return EXIT_FAILURE;
+	}
+
+	char* keys_data = read_keys_file_content(keys_file_path);
+	if (keys_data == NULL){
+		return EXIT_FAILURE;
+	}
+
+	char* key = NULL;
+	char* iv = NULL;
+	parse_key_lines(keys_data, &key, &iv);
+	free(keys_data);
+
+	if (key == NULL || iv == NULL){
+		printf("Loading AES key and/or AES iv failed!\n");
+		free(key);
+		free(iv);
+		return EXIT_FAILURE;
+	}
+
+	printf("Using AES Key \t\t'%s'\n", key);
+	printf("Using AES IV \t\t'%s'\n", iv);
+	printf("Input file path \t'%s'\n", input_file_path);
+	printf("Output file path \t'%s'\n", output_file_path);
+	printf("Decrypting \t\t'%s'\n\n", (decryptParam) ? "true" : "false");
+
+	unsigned char key_digest[EVP_MAX_MD_SIZE];
+	unsigned char iv_digest[EVP_MAX_MD_SIZE];
+	generate_sha256_hash((char*) key, key_digest);
+	generate_sha256_hash((char*) iv, iv_digest);
+
+	zchunk_t* input_chunk = zchunk_slurp (input_file_path, 0);
+	if (input_chunk == NULL){
+		printf("Input file not correct!\n");
+		free(key);
+		free(iv);
+		return EXIT_FAILURE;
+	}
+
+	//Load input data from file
+	int input_file_size = (int) zchunk_size (input_chunk);
+	char* input_file_data = zchunk_strdup(input_chunk);
+	zchunk_destroy (&input_chunk);
+
+	int output_len;
+	unsigned char output[input_file_size];
+	if (decryptParam){
+		output_len = decrypt_aes((unsigned char*) input_file_data, input_file_size, key_digest, iv_digest, output);
+		output[output_len] = '\0';
+	}else{
+		output_len = encrypt_aes((unsigned char*) input_file_data, input_file_size, key_digest, iv_digest, output);
+	}
+
+	//Write output data to file
+	zfile_t* output_file = zfile_new (".", output_file_path);
+	zchunk_t* output_chunk = zchunk_new(output, output_len);
+	rc = zfile_output (output_file);
+	if (rc != 0){
+		printf("Problem with opening file for writing!\n");
+		zchunk_destroy (&output_chunk);
+		zfile_close (output_file);
+		zfile_destroy (&output_file);
+		free(input_file_data);
+		free(key);
+		free(iv);
+
+		return EXIT_FAILURE;
+	}
+
+	rc = zfile_write (output_file, output_chunk, 0);
+	if (rc != 0){
+		printf("Problem with writing output to file!\n");
+	}
+	printf("Output written to file:\n");
+	if (decryptParam){
+		printf("%s\n", output);
+	}else{
+		BIO_dump_fp (stdout, (const char *) output, output_len);
+	}
+
+	zchunk_destroy (&output_chunk);
+	zfile_close (output_file);
+	zfile_destroy (&output_file);
+	free(input_file_data);
+	free(key);
+	free(iv);
+
+	return EXIT_SUCCESS;
+}
+
+int generate_sha256_hash(char* text, unsigned char* digest)
+{
+	unsigned int digest_len;
+
+	EVP_MD_CTX * mdctx = EVP_MD_CTX_new();
+	EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
+	EVP_DigestUpdate(mdctx, text, strlen(text));
+	EVP_DigestFinal_ex(mdctx, digest, &digest_len);
+	EVP_MD_CTX_free(mdctx);
+
+	return digest_len;
+}
+
+int encrypt_aes(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext)
+{
+	int len;
+	int ciphertext_len;
+
+	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
+
+	EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
+	EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len);
+	ciphertext_len = len;
+	EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
+	ciphertext_len += len;
+
+	EVP_CIPHER_CTX_free(ctx);
+
+	return ciphertext_len;
+}
+
+int decrypt_aes(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext)
+{
+	int len;
+	int plaintext_len;
+
+	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
+
+	EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
+	EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);
+	plaintext_len = len;
+	EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
+	plaintext_len += len;
+
+	EVP_CIPHER_CTX_free(ctx);
+
+	return plaintext_len;
+}
+
+static char* read_keys_file_content(const char *keys_file_path){
+	char* keys_file_full_path = strndup(keys_file_path, MAX_KEY_FILE_LENGTH);
+	char* keys_file_name = NULL;
+
+	char* sep_kf_at = strrchr(keys_file_path, '/');
+	if (sep_kf_at != NULL){
+		*sep_kf_at = '\0';
+		keys_file_name = sep_kf_at + 1;
+	}else{
+		keys_file_name = (char*) keys_file_path;
+		keys_file_path = (const char*) ".";
+	}
+
+	printf("Keys file path: %s\n", keys_file_full_path);
+
+	int rc = 0;
+
+	zfile_t* keys_file = zfile_new (keys_file_path, keys_file_name);
+	rc = zfile_input (keys_file);
+	if (rc != 0){
+		printf("Keys file '%s' not readable!\n", keys_file_full_path);
+		zfile_destroy(&keys_file);
+		free(keys_file_full_path);
+		return NULL;
+	}
+
+	ssize_t keys_file_size = zsys_file_size (keys_file_full_path);
+	zchunk_t* keys_chunk = zfile_read (keys_file, keys_file_size, 0);
+	if (keys_chunk == NULL){
+		printf("Can't read file '%s'!\n", keys_file_full_path);
+		zfile_close(keys_file);
+		zfile_destroy(&keys_file);
+		free(keys_file_full_path);
+		return NULL;
+	}
+
+	char* keys_data = zchunk_strdup(keys_chunk);
+	zchunk_destroy(&keys_chunk);
+	zfile_close(keys_file);
+	zfile_destroy (&keys_file);
+
+	return keys_data;
+}
+
+static void parse_key_lines(char *keysBuffer, char **key, char **iv){
+	char *line = NULL, *saveLinePointer = NULL;
+
+	bool firstTime = true;
+	do {
+		if (firstTime){
+			line = strtok_r(keysBuffer, "\n", &saveLinePointer);
+			firstTime = false;
+		}else {
+			line = strtok_r(NULL, "\n", &saveLinePointer);
+		}
+
+		if (line == NULL){
+			break;
+		}
+
+		parse_key_line(line, key, iv);
+
+	} while((*key == NULL || *iv == NULL) && line != NULL);
+
+}
+
+static void parse_key_line(char *line, char **key, char **iv){
+	char *detectedKey = NULL, *detectedValue= NULL;
+
+	char* sep_at = strchr(line, ':');
+	if (sep_at == NULL){
+		return;
+	}
+
+	*sep_at = '\0'; // overwrite first separator, creating two strings.
+	detectedKey = line;
+	detectedValue = sep_at + 1;
+
+	if (detectedKey == NULL || detectedValue == NULL){
+		return;
+	}
+	if (detectedKey[0] == '\0' || detectedValue[0] == '\0'){
+		return;
+	}
+
+	if (*key == NULL && strcmp(detectedKey, KEY_TO_GET) == 0){
+		*key = strndup(detectedValue, AES_KEY_LENGTH);
+	} else if (*iv == NULL && strcmp(detectedKey, IV_TO_GET) == 0){
+		*iv = strndup(detectedValue, AES_IV_LENGTH);
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/keygen/makecert.c
----------------------------------------------------------------------
diff --git a/bundles/pubsub/keygen/makecert.c b/bundles/pubsub/keygen/makecert.c
new file mode 100644
index 0000000..166111e
--- /dev/null
+++ b/bundles/pubsub/keygen/makecert.c
@@ -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.
+ */
+/*
+ * makecert.c
+ *
+ *  \date       Dec 2, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <string.h>
+
+#include "czmq.h"
+
+int main (int argc, const char * argv[])
+{
+
+	const char * cert_name_public = "certificate.pub";
+	const char * cert_name_secret = "certificate.key";
+	if (argc == 3 && strcmp(argv[1], argv[2]) != 0){
+		cert_name_public = argv[1];
+		cert_name_secret = argv[2];
+	}
+
+	zcert_t * cert = zcert_new();
+
+	char *timestr = zclock_timestr ();
+	zcert_set_meta (cert, "date-created", timestr);
+	free (timestr);
+
+	zcert_save_public(cert, cert_name_public);
+	zcert_save_secret(cert, cert_name_secret);
+	zcert_print (cert);
+	printf("\n");
+	printf("I: CURVE certificate created in %s and %s\n", cert_name_public, cert_name_secret);
+	zcert_destroy (&cert);
+
+	return 0;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/mock/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/mock/CMakeLists.txt b/bundles/pubsub/mock/CMakeLists.txt
new file mode 100644
index 0000000..c310e1b
--- /dev/null
+++ b/bundles/pubsub/mock/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.
+
+#only install if CppuTest is available
+find_package(CppUTest QUIET)
+if (CPPUTEST_FOUND)
+
+    add_library(pubsub_mock STATIC
+            src/publisher_mock.cc
+    )
+    target_include_directories(pubsub_mock PUBLIC api)
+    target_link_libraries(pubsub_mock PRIVATE Celix::pubsub_spi ${CPPUTEST_LIBRARY})
+    target_include_directories(pubsub_mock SYSTEM PRIVATE 
+        ${CPPUTEST_INCLUDE_DIR}
+    )
+
+    if (ENABLE_TESTING)
+        add_executable(pubsubmock_test
+            tst/pubsubmock_test.cc
+            tst/run_tests.cc
+        )
+        target_include_directories(pubsubmock_test PRIVATE ${CMAKE_CURRENT_LIST_DIR}/api)
+	target_link_libraries(pubsubmock_test PRIVATE Celix::pubsub_api pubsub_mock ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} Celix::framework)
+        add_test(NAME pubsubmock_test COMMAND pubsubmock_test)
+    endif()
+endif()
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/mock/api/pubsub/publisher_mock.h
----------------------------------------------------------------------
diff --git a/bundles/pubsub/mock/api/pubsub/publisher_mock.h b/bundles/pubsub/mock/api/pubsub/publisher_mock.h
new file mode 100644
index 0000000..45c69db
--- /dev/null
+++ b/bundles/pubsub/mock/api/pubsub/publisher_mock.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.
+ */
+#ifndef PUBSUB_PUBLISHER_MOCK_H_
+#define PUBSUB_PUBLISHER_MOCK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pubsub/publisher.h" 
+
+#define PUBSUB_PUBLISHERMOCK_SCOPE "pubsub_publisher"
+#define PUBSUB_PUBLISHERMOCK_LOCAL_MSG_TYPE_ID_FOR_MSG_TYPE_METHOD "pubsub__publisherMock_localMsgTypeIdForMsgType"
+#define PUBSUB_PUBLISHERMOCK_SEND_METHOD "pubsub__publisherMock_send"
+#define PUBSUB_PUBLISHERMOCK_SEND_MULTIPART_METHOD "pubsub__publisherMock_sendMultipart"
+
+
+/*============================================================================
+  MOCK - intialize publisher mock
+  ============================================================================*/
+void pubsub_publisherMock_init(pubsub_publisher_t* srv, void* handle);
+  
+#ifdef __cplusplus
+}
+#endif
+
+#endif //PUBSUB_PUBLISHER_MOCK_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/mock/src/publisher_mock.cc
----------------------------------------------------------------------
diff --git a/bundles/pubsub/mock/src/publisher_mock.cc b/bundles/pubsub/mock/src/publisher_mock.cc
new file mode 100644
index 0000000..e8902a8
--- /dev/null
+++ b/bundles/pubsub/mock/src/publisher_mock.cc
@@ -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.
+ */
+#include "pubsub/publisher_mock.h"
+#include "CppUTest/TestHarness.h"
+#include "CppUTestExt/MockSupport.h"
+
+/*============================================================================
+  MOCK - mock function for pubsub_publisher->localMsgTypeIdForMsgType
+  ============================================================================*/
+static int pubsub__publisherMock_localMsgTypeIdForMsgType(void *handle, const char *msgType, unsigned int *msgTypeId) {
+    return mock(PUBSUB_PUBLISHERMOCK_SCOPE)
+        .actualCall(PUBSUB_PUBLISHERMOCK_LOCAL_MSG_TYPE_ID_FOR_MSG_TYPE_METHOD)
+        .withPointerParameter("handle", handle)
+        .withParameter("msgType", msgType)
+        .withOutputParameter("msgTypeId", msgTypeId)
+        .returnIntValue();
+}
+
+/*============================================================================
+  MOCK - mock function for pubsub_publisher->send
+  ============================================================================*/
+static int pubsub__publisherMock_send(void *handle, unsigned int msgTypeId, const void *msg) {
+    return mock(PUBSUB_PUBLISHERMOCK_SCOPE)
+        .actualCall(PUBSUB_PUBLISHERMOCK_SEND_METHOD)
+        .withPointerParameter("handle", handle)
+        .withParameter("msgTypeId", msgTypeId)
+        .withPointerParameter("msg", (void*)msg)
+        .returnIntValue();
+}
+
+/*============================================================================
+  MOCK - mock function for pubsub_publisher->sendMultipart
+  ============================================================================*/
+static int pubsub__publisherMock_sendMultipart(void *handle, unsigned int msgTypeId, const void *msg, int flags) {
+    return mock(PUBSUB_PUBLISHERMOCK_SCOPE)
+        .actualCall(PUBSUB_PUBLISHERMOCK_SEND_MULTIPART_METHOD)
+        .withPointerParameter("handle", handle)
+        .withParameter("msgTypeId", msgTypeId)
+        .withPointerParameter("msg", (void*)msg)
+        .withParameter("flags", flags)
+        .returnIntValue();
+}
+
+/*============================================================================
+  MOCK - mock setup for publisher service
+  ============================================================================*/
+void pubsub_publisherMock_init(pubsub_publisher_t* srv, void* handle) {
+    srv->handle = handle;
+    srv->localMsgTypeIdForMsgType = pubsub__publisherMock_localMsgTypeIdForMsgType;
+    srv->send = pubsub__publisherMock_send;
+    srv->sendMultipart = pubsub__publisherMock_sendMultipart;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/mock/tst/pubsubmock_test.cc
----------------------------------------------------------------------
diff --git a/bundles/pubsub/mock/tst/pubsubmock_test.cc b/bundles/pubsub/mock/tst/pubsubmock_test.cc
new file mode 100644
index 0000000..16f2058
--- /dev/null
+++ b/bundles/pubsub/mock/tst/pubsubmock_test.cc
@@ -0,0 +1,77 @@
+/**
+ *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 <CppUTestExt/MockSupport.h>
+#include <CppUTest/TestHarness.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "pubsub/publisher_mock.h"
+
+
+static pubsub_publisher_t mockSrv;
+static void* mockHandle = (void*)0x42;
+
+
+TEST_GROUP(pubsubmock) {
+    void setup(void) {
+    	//setup mock
+    	pubsub_publisherMock_init(&mockSrv, mockHandle);
+    }
+
+    void teardown() {
+        mock().checkExpectations();
+        mock().clear();
+    }
+};
+
+TEST(pubsubmock, publishermock) {
+    const char* mockFqn = "example.Msg";
+    unsigned int mockOutputTypeId = 11;
+
+    mock(PUBSUB_PUBLISHERMOCK_SCOPE).expectOneCall(PUBSUB_PUBLISHERMOCK_LOCAL_MSG_TYPE_ID_FOR_MSG_TYPE_METHOD)
+        .withParameter("handle", mockHandle)
+	.withParameter("msgType", mockFqn)
+	.withOutputParameterReturning("msgTypeId", &mockOutputTypeId, sizeof(mockOutputTypeId));
+
+    mock(PUBSUB_PUBLISHERMOCK_SCOPE).expectOneCall(PUBSUB_PUBLISHERMOCK_SEND_METHOD)
+        .withParameter("handle", mockHandle)
+        .withParameter("msgTypeId", mockOutputTypeId)
+        .ignoreOtherParameters();
+
+    //This should normally be code which should be tested, for now it code to verify the mock
+    pubsub_publisher_t* srv = &mockSrv;
+    const char* msgFqn = "example.Msg";
+    unsigned int msgId = 0;
+
+    //get type id (normally only if type id is not yet set (e.g. 0))
+    srv->localMsgTypeIdForMsgType(srv->handle, msgFqn, &msgId);
+    CHECK(msgId != 0);
+
+    //set msg
+    void *dummyMsg = (void*)0x43; 
+    srv->send(srv->handle, msgId, dummyMsg); //should satify the expectOneCalls 
+    //srv->send(srv->handle, msgId, dummyMsg); //enabling this should fail the test
+
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/mock/tst/run_tests.cc
----------------------------------------------------------------------
diff --git a/bundles/pubsub/mock/tst/run_tests.cc b/bundles/pubsub/mock/tst/run_tests.cc
new file mode 100644
index 0000000..7f93791
--- /dev/null
+++ b/bundles/pubsub/mock/tst/run_tests.cc
@@ -0,0 +1,25 @@
+/**
+ *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 <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+int main(int argc, char** argv) {
+    return RUN_ALL_TESTS(argc, argv);
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/pubsub/pubsub_admin_udp_mc/CMakeLists.txt b/bundles/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
new file mode 100644
index 0000000..42bd1b7
--- /dev/null
+++ b/bundles/pubsub/pubsub_admin_udp_mc/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.
+
+find_package(Jansson REQUIRED)
+
+add_celix_bundle(celix_pubsub_admin_udp_multicast
+	BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_udp_multicast"
+	VERSION "1.0.0"
+	SOURCES
+        src/psa_activator.c
+        src/pubsub_admin_impl.c
+        src/topic_subscription.c
+        src/topic_publication.c
+        src/large_udp.c
+)
+target_include_directories(celix_pubsub_admin_udp_multicast PRIVATE
+		src
+		${JANSSON_INCLUDE_DIR}
+)
+set_target_properties(celix_pubsub_admin_udp_multicast PROPERTIES INSTALL_RPATH "$ORIGIN")
+target_link_libraries(celix_pubsub_admin_udp_multicast PRIVATE Celix::pubsub_spi Celix::framework Celix::dfi Celix::log_helper)
+
+install_celix_bundle(celix_pubsub_admin_udp_multicast EXPORT celix COMPONENT pubsub)
+
+add_library(Celix::pubsub_admin_udp_multicast ALIAS celix_pubsub_admin_udp_multicast)
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/pubsub/pubsub_admin_udp_mc/README.md
----------------------------------------------------------------------
diff --git a/bundles/pubsub/pubsub_admin_udp_mc/README.md b/bundles/pubsub/pubsub_admin_udp_mc/README.md
new file mode 100644
index 0000000..7520fef
--- /dev/null
+++ b/bundles/pubsub/pubsub_admin_udp_mc/README.md
@@ -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.
+-->
+
+# PUBSUB-Admin UDP Multicast
+
+---
+
+## Description
+
+This description is particular for the UDP-Multicast PUB-SUB. 
+
+The UDP multicast pubsub admin is used to transfer user data transparent via UDP multicast. UDP packets can contain approximately  
+64kB . To overcome this limit the admin has a protocol on top of UDP which fragments the data to be send and these  
+fragments are reassembled at the reception side.
+
+### IP Addresses
+
+To use UDP-multicast 2 IP adresses are needed:
+
+1. IP address which is bound to an (ethernet) interface
+2. The multicast address (in the range 224.X.X.X - 239.X.X.X)
+
+When the PubSubAdmin starts it determines the bound IP address. This is done in the order:
+
+1. The first IP number bound to the interface which is set by the "PSA_INTERFACE" property
+2. The interfaces are iterated and the first IP number found is used. (typically this is 127.0.0.1 (localhost)
+
+The  Multicass IP address is determined in the order:
+
+1. If the `PSA_IP` property is defined, this IP will be used as multicast.
+2. If the `PSA_MC_PREFIX` property, is defined, this property is used as the first 2 numbers of the multicast address extended with the last 2 numbers of the bound IP.
+3. If the `PSA_MC_PREFIX` property is not defined `224.100` is used.
+
+### Discovery
+
+When a publisher request for a topic a TopicSender is created by a ServiceFactory. This TopicSender uses the multicast address as described above with a random chosen portnumber. The combination of the multicast-IP address with the portnumber and protocol(udp) is the endpoint.  
+This endpoint is published by the PubSubDiscovery within its topic in ETCD (i.e. udp://224.100.10.20:40123).
+ 
+A subscriber, interested in the topic, is informed by the the ToplogyManager that there is a new endpoint. The TopicReceiver at the subscriber side creates a listening socket based on this endpoint. 
+
+Now a data-connection is created and data send by the publisher will be received by the subscriber.  
+
+---
+
+## Properties
+
+<table border="1">
+    <tr><th>Property</th><th>Description</th></tr>
+    <tr><td>PSA_INTERFACE</td><td>Interface which has to be used for multicast communication</td></tr>
+    <tr><td>PSA_IP</td><td>Multicast IP address used by the bundle</td></tr>
+    <tr><td>PSA_MC_PREFIX</td><td>First 2 digits of the MC IP address </td></tr>
+</table>
+
+---
+
+## Shortcomings
+
+1. Per topic a random portnr is used for creating an endpoint. It is theoretical possible that for 2 topic the same endpoint is created.
+2. For every message a 32 bit random message ID is generated to discriminate segments of different messages which could be sent at the same time. It is theoretically possible that there are 2 equal message ID's at the same time. But since the mesage ID is valid only during the transmission of a message (maximum some milliseconds with large messages) this is not very plausible.
+3. When sending large messages, these messages are segmented and sent after each other. This could cause UDP-buffer overflows in the kernel. A solution could be to add a delay between sending of the segements but this will introduce extra latency.
+4. A Hash is created, using the message definition, to identify the message type. When 2 messages generate the same hash something will terribly go wrong. A check should be added to prevent this (or another way to identify the message type). This problem is also valid for the other admins.
+
+
+
+