You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2017/02/06 14:23:05 UTC

[6/6] celix git commit: CELIX-389: Adds Celix Publish Subscribe donation.

CELIX-389: Adds Celix Publish Subscribe donation.


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

Branch: refs/heads/develop
Commit: f9a5fb11e28b642c33a84de8f3e53215e0065ad6
Parents: 3e67852
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Feb 6 15:21:04 2017 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Feb 6 15:21:04 2017 +0100

----------------------------------------------------------------------
 celix-pubsub/cmake/FindCZMQ.cmake               |  42 +
 celix-pubsub/cmake/FindZMQ.cmake                |  42 +
 celix-pubsub/pubsub/CMakeLists.txt              |  48 ++
 celix-pubsub/pubsub/README.md                   |  71 ++
 celix-pubsub/pubsub/api/pubsub/publisher.h      |  88 +++
 celix-pubsub/pubsub/api/pubsub/subscriber.h     |  75 ++
 celix-pubsub/pubsub/deploy/CMakeLists.txt       | 123 +++
 celix-pubsub/pubsub/examples/CMakeLists.txt     |  19 +
 celix-pubsub/pubsub/examples/keys/README.md     |  19 +
 .../examples/keys/publisher/private/.gitkeep    |   0
 .../examples/keys/publisher/public/.gitkeep     |   0
 .../examples/keys/subscriber/private/.gitkeep   |   0
 .../examples/keys/subscriber/public/.gitkeep    |   0
 .../pubsub/examples/mp_pubsub/CMakeLists.txt    |  23 +
 .../examples/mp_pubsub/common/include/ew.h      |  53 ++
 .../examples/mp_pubsub/common/include/ide.h     |  49 ++
 .../mp_pubsub/common/include/kinematics.h       |  55 ++
 .../mp_pubsub/msg_descriptors/msg_ew.descriptor |   9 +
 .../msg_descriptors/msg_ide.descriptor          |   9 +
 .../msg_descriptors/msg_kinematics.descriptor   |  10 +
 .../examples/mp_pubsub/publisher/CMakeLists.txt |  48 ++
 .../private/include/mp_publisher_private.h      |  58 ++
 .../publisher/private/src/mp_pub_activator.c    | 150 ++++
 .../publisher/private/src/mp_publisher.c        | 161 ++++
 .../mp_pubsub/subscriber/CMakeLists.txt         |  48 ++
 .../private/include/mp_subscriber_private.h     |  51 ++
 .../subscriber/private/src/mp_sub_activator.c   | 117 +++
 .../subscriber/private/src/mp_subscriber.c      | 119 +++
 .../pubsub/examples/pubsub/CMakeLists.txt       |  24 +
 .../pubsub/examples/pubsub/common/include/poi.h |  55 ++
 .../pubsub/msg_descriptors/msg_poi1.descriptor  |  10 +
 .../pubsub/msg_descriptors/msg_poi2.descriptor  |  10 +
 .../pubsub/msg_descriptors/poi1.properties      |  18 +
 .../pubsub/msg_descriptors/poi2.properties      |  18 +
 .../examples/pubsub/publisher/CMakeLists.txt    |  52 ++
 .../private/include/pubsub_publisher_private.h  |  60 ++
 .../publisher/private/src/ps_pub_activator.c    | 157 ++++
 .../publisher/private/src/pubsub_publisher.c    | 164 ++++
 .../examples/pubsub/publisher2/CMakeLists.txt   |  54 ++
 .../examples/pubsub/subscriber/CMakeLists.txt   |  53 ++
 .../private/include/pubsub_subscriber_private.h |  52 ++
 .../subscriber/private/src/ps_sub_activator.c   | 123 +++
 .../subscriber/private/src/pubsub_subscriber.c  |  64 ++
 celix-pubsub/pubsub/keygen/CMakeLists.txt       |  34 +
 celix-pubsub/pubsub/keygen/ed_file.c            | 309 ++++++++
 celix-pubsub/pubsub/keygen/makecert.c           |  55 ++
 .../pubsub/pubsub_admin_udp_mc/CMakeLists.txt   |  57 ++
 .../pubsub/pubsub_admin_udp_mc/README.md        |  62 ++
 .../private/include/large_udp.h                 |  45 ++
 .../private/include/pubsub_admin_impl.h         |  71 ++
 .../include/pubsub_publish_service_private.h    |  55 ++
 .../private/include/topic_subscription.h        |  55 ++
 .../pubsub_admin_udp_mc/private/src/large_udp.c | 362 +++++++++
 .../private/src/psa_activator.c                 | 113 +++
 .../private/src/pubsub_admin_impl.c             | 670 ++++++++++++++++
 .../private/src/topic_publication.c             | 470 ++++++++++++
 .../private/src/topic_subscription.c            | 497 ++++++++++++
 .../pubsub/pubsub_admin_zmq/CMakeLists.txt      |  70 ++
 .../private/include/pubsub_admin_impl.h         |  86 +++
 .../include/pubsub_publish_service_private.h    |  47 ++
 .../private/include/topic_subscription.h        |  57 ++
 .../private/include/zmq_crypto.h                |  41 +
 .../private/src/psa_activator.c                 | 112 +++
 .../private/src/pubsub_admin_impl.c             | 699 +++++++++++++++++
 .../private/src/topic_publication.c             | 605 +++++++++++++++
 .../private/src/topic_subscription.c            | 741 ++++++++++++++++++
 .../pubsub_admin_zmq/private/src/zmq_crypto.c   | 281 +++++++
 .../public/include/dyn_msg_utils.h              |  39 +
 .../pubsub/pubsub_common/public/include/etcd.h  |  39 +
 .../include/publisher_endpoint_announce.h       |  36 +
 .../pubsub_common/public/include/pubsub_admin.h |  56 ++
 .../public/include/pubsub_common.h              |  51 ++
 .../public/include/pubsub_endpoint.h            |  49 ++
 .../public/include/pubsub_serializer.h          |  47 ++
 .../public/include/pubsub_topic_info.descriptor |  10 +
 .../pubsub_common/public/include/pubsub_utils.h |  39 +
 .../pubsub_common/public/src/dyn_msg_utils.c    | 156 ++++
 .../pubsub/pubsub_common/public/src/etcd.c      | 476 ++++++++++++
 .../pubsub_common/public/src/log_helper.c       | 209 +++++
 .../pubsub_common/public/src/pubsub_endpoint.c  | 156 ++++
 .../public/src/pubsub_serializer.c              | 105 +++
 .../pubsub_common/public/src/pubsub_utils.c     | 163 ++++
 .../pubsub/pubsub_discovery/CMakeLists.txt      |  43 ++
 .../private/include/etcd_common.h               |  28 +
 .../private/include/etcd_watcher.h              |  38 +
 .../private/include/etcd_writer.h               |  39 +
 .../private/include/pubsub_discovery_impl.h     |  73 ++
 .../pubsub_discovery/private/src/etcd_common.c  |  81 ++
 .../pubsub_discovery/private/src/etcd_watcher.c | 292 +++++++
 .../pubsub_discovery/private/src/etcd_writer.c  | 189 +++++
 .../private/src/psd_activator.c                 | 171 +++++
 .../private/src/pubsub_discovery_impl.c         | 468 ++++++++++++
 .../public/include/pubsub_discovery.h           |  26 +
 .../pubsub_topology_manager/CMakeLists.txt      |  43 ++
 .../private/include/pubsub_topology_manager.h   |  86 +++
 .../private/src/pstm_activator.c                | 233 ++++++
 .../private/src/pubsub_topology_manager.c       | 758 +++++++++++++++++++
 97 files changed, 12194 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/cmake/FindCZMQ.cmake
----------------------------------------------------------------------
diff --git a/celix-pubsub/cmake/FindCZMQ.cmake b/celix-pubsub/cmake/FindCZMQ.cmake
new file mode 100644
index 0000000..4f4891c
--- /dev/null
+++ b/celix-pubsub/cmake/FindCZMQ.cmake
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+# - Try to find CZMQ
+# 	Once done this will define
+#  CZMQ_FOUND - System has Zmq
+#  CZMQ_INCLUDE_DIRS - The Zmq include directories
+#  CZMQ_LIBRARIES - The libraries needed to use Zmq
+#  CZMQ_DEFINITIONS - Compiler switches required for using Zmq
+
+find_path(CZMQ_INCLUDE_DIR czmq.h
+          /usr/include
+          /usr/local/include )
+
+find_library(CZMQ_LIBRARY NAMES czmq
+             PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64 )
+
+set(CZMQ_LIBRARIES ${CZMQ_LIBRARY} )
+set(CZMQ_INCLUDE_DIRS ${CZMQ_INCLUDE_DIR} )
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set CZMQ_FOUND to TRUE
+# if all listed variables are TRUE
+find_package_handle_standard_args(Czmq  DEFAULT_MSG
+                                  CZMQ_LIBRARY CZMQ_INCLUDE_DIR)
+
+mark_as_advanced(CZMQ_INCLUDE_DIR CZMQ_LIBRARY )

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/cmake/FindZMQ.cmake
----------------------------------------------------------------------
diff --git a/celix-pubsub/cmake/FindZMQ.cmake b/celix-pubsub/cmake/FindZMQ.cmake
new file mode 100644
index 0000000..b2c2663
--- /dev/null
+++ b/celix-pubsub/cmake/FindZMQ.cmake
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+# - Try to find ZMQ
+# 	Once done this will define
+#  ZMQ_FOUND - System has Zmq
+#  ZMQ_INCLUDE_DIRS - The Zmq include directories
+#  ZMQ_LIBRARIES - The libraries needed to use Zmq
+#  ZMQ_DEFINITIONS - Compiler switches required for using Zmq
+
+find_path(ZMQ_INCLUDE_DIR zmq.h zmq_utils.h
+          /usr/include
+          /usr/local/include )
+
+find_library(ZMQ_LIBRARY NAMES zmq
+             PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64 )
+
+set(ZMQ_LIBRARIES ${ZMQ_LIBRARY} )
+set(ZMQ_INCLUDE_DIRS ${ZMQ_INCLUDE_DIR} )
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set ZMQ_FOUND to TRUE
+# if all listed variables are TRUE
+find_package_handle_standard_args(Zmq  DEFAULT_MSG
+                                  ZMQ_LIBRARY ZMQ_INCLUDE_DIR)
+
+mark_as_advanced(ZMQ_INCLUDE_DIR ZMQ_LIBRARY )

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/CMakeLists.txt b/celix-pubsub/pubsub/CMakeLists.txt
new file mode 100644
index 0000000..c61aaeb
--- /dev/null
+++ b/celix-pubsub/pubsub/CMakeLists.txt
@@ -0,0 +1,48 @@
+# 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)
+if (PUBSUB)
+
+	include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+	include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+
+	option(ENABLE_ZMQ_SECURITY "Enable security for ZeroMQ" OFF)
+	
+	set (PUBSUB_SERIALIZER_SRC "${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_serializer.c")
+	set (SERIALIZER_PATH "" CACHE FILEPATH "Path to the directory which will contain the serializer (include / src).")
+	set (SERIALIZER_LIB_INCLUDE_DIR "" CACHE FILEPATH "Path to the include dir of the addiotional libs.")
+	set (SERIALIZER_LIB_PATH "" CACHE FILEPATH "Path to the additional library.")
+	if (EXISTS ${SERIALIZER_PATH})
+		file (GLOB PUBSUB_SERIALIZER_SRC ${SERIALIZER_PATH}/src/*.c)
+		
+		if (SERIALIZER_LIB_PATH)
+			get_filename_component(SERIALIZER_LIB_DIR ${SERIALIZER_LIB_PATH} DIRECTORY)
+			get_filename_component(SERIALIZER_LIB_FULLNAME ${SERIALIZER_LIB_PATH} NAME_WE)
+			string (REPLACE "lib" "" SERIALIZER_LIBRARY ${SERIALIZER_LIB_FULLNAME})
+		endif()
+	endif()
+	
+	add_subdirectory(pubsub_topology_manager)
+	add_subdirectory(pubsub_discovery)
+	add_subdirectory(pubsub_admin_zmq)
+	add_subdirectory(pubsub_admin_udp_mc)
+	add_subdirectory(examples)
+	add_subdirectory(deploy)
+	add_subdirectory(keygen)
+	
+endif(PUBSUB)

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/README.md
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/README.md b/celix-pubsub/pubsub/README.md
new file mode 100644
index 0000000..5980695
--- /dev/null
+++ b/celix-pubsub/pubsub/README.md
@@ -0,0 +1,71 @@
+# PubSubAdmin
+
+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
+
+To get the ZeroMQ pubsub admin running, [ZeroMQ](https://github.com/zeromq/libzmq) and [CZMQ](https://github.com/zeromq/czmq) needs to be installed.
+
+Also, to make use of encrypted traffic, [OpenSSL] is required.
+[OpenSSL github repo](https://github.com/openssl/openssl)
+
+## Running instructions
+
+### 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`
+1. Run `echo "aes_iv:{AES_IV here}" >> ~/pubsub.keys`
+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. To generate ZMQ keypairs
+1. Run `pubsub/keygen/makecert cert_topic1.pub cert_topic1.key`
+1. To encrypt files
+1. Run `pubsub/keygen/ed_file ~/pubsub.keys cert_topic1.key cert_topic1.key.enc`
+1. Store the keys in the pubsub/examples/keys/ directory
+1. Build project to include these keys
+
+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`
+
+### 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
+

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/api/pubsub/publisher.h
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/api/pubsub/publisher.h b/celix-pubsub/pubsub/api/pubsub/publisher.h
new file mode 100644
index 0000000..58ac589
--- /dev/null
+++ b/celix-pubsub/pubsub/api/pubsub/publisher.h
@@ -0,0 +1,88 @@
+/**
+ *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.h
+ *
+ *  \date       Jan 7, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef __PUBSUB_PUBLISHER_H_
+#define __PUBSUB_PUBLISHER_H_
+
+#include <stdlib.h>
+
+#define PUBSUB_PUBLISHER_SERVICE_NAME           "pubsub.publisher"
+#define PUBSUB_PUBLISHER_SERVICE_VERSION        "1.0.0"
+ 
+//properties
+#define PUBSUB_PUBLISHER_TOPIC                  "pubsub.topic"
+#define PUBSUB_PUBLISHER_SCOPE                  "pubsub.scope"
+#define PUBSUB_PUBLISHER_STRATEGY               "pubsub.strategy"
+#define PUBSUB_PUBLISHER_CONFIG                 "pubsub.config"
+ 
+#define PUBSUB_PUBLISHER_SCOPE_DEFAULT			"default"
+//flags
+#define PUBSUB_PUBLISHER_FIRST_MSG  01
+#define PUBSUB_PUBLISHER_PART_MSG   02
+#define PUBSUB_PUBLISHER_LAST_MSG   04
+
+struct pubsub_release_callback_struct {
+    void *handle;
+    void (*release)(char *buf, void *handle);
+};
+typedef struct pubsub_release_callback_struct pubsub_release_callback_t;
+typedef struct pubsub_release_callback_struct* pubsub_release_callback_pt;
+ 
+ 
+struct pubsub_publisher {
+    void *handle;
+ 
+    /**
+     * Every msg is identifiable by msg type string. Because masg type string are performance wise not preferable (string compares),
+     * a "local" (int / platform dependent) unique id will be generated runtime
+     * with use of a distributed key/value store or communication between  participation parties.
+     * this is called the local message type id. This local message type id can be requested with the localMsgIdForMsgType method.
+     * When return is successful the msgTypeId is always greater than 0. (Note this can be used to specify/detect uninitialized msg type ids in the consumer code).
+     *
+     * Returns 0 on success.
+     */
+    int (*localMsgTypeIdForMsgType)(void *handle, const char *msgType, unsigned int *msgTypeId);
+  
+    /**
+     * send is a async function, but the msg can be safely deleted after send returns.
+     * Returns 0 on success.
+     */
+    int (*send)(void *handle, unsigned int msgTypeId, void *msg);
+ 
+  
+    /**
+     * sendMultipart is a async function, but the msg can be safely deleted after send returns.
+     * The first (primary) message of a multipart message must have the flag PUBLISHER_PRIMARY_MSG
+     * The last message of a multipart message must have the flag PUBLISHER_LAST_MSG
+     * Returns 0 on success.
+     */
+    int (*sendMultipart)(void *handle, unsigned int msgTypeId, void *msg, int flags);
+ 
+};
+typedef struct pubsub_publisher pubsub_publisher_t;
+typedef struct pubsub_publisher* pubsub_publisher_pt;
+
+#endif // __PUBSUB_PUBLISHER_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/api/pubsub/subscriber.h
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/api/pubsub/subscriber.h b/celix-pubsub/pubsub/api/pubsub/subscriber.h
new file mode 100644
index 0000000..cbbe96c
--- /dev/null
+++ b/celix-pubsub/pubsub/api/pubsub/subscriber.h
@@ -0,0 +1,75 @@
+/**
+ *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.
+ */
+/*
+ * subscriber.h
+ *
+ *  \date       Jan 7, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef __PUBSUB_SUBSCRIBER_H_
+#define __PUBSUB_SUBSCRIBER_H_
+
+#include <stdbool.h>
+
+#define PUBSUB_SUBSCRIBER_SERVICE_NAME          "pubsub.subscriber"
+#define PUBSUB_SUBSCRIBER_SERVICE_VERSION       "1.0.0"
+ 
+//properties
+#define PUBSUB_SUBSCRIBER_TOPIC                "pubsub.topic"
+#define PUBSUB_SUBSCRIBER_SCOPE                "pubsub.scope"
+#define PUBSUB_SUBSCRIBER_STRATEGY             "pubsub.strategy"
+#define PUBSUB_SUBSCRIBER_CONFIG               "pubsub.config"
+
+#define PUBSUB_SUBSCRIBER_SCOPE_DEFAULT        "default"
+ 
+struct pubsub_multipart_callbacks_struct {
+    void *handle;
+    int (*localMsgTypeIdForMsgType)(void *handle, const char *msgType, unsigned int *msgId);
+    int (*getMultipart)(void *handle, unsigned int msgTypeId, bool retain, void **part);
+};
+typedef struct pubsub_multipart_callbacks_struct pubsub_multipart_callbacks_t;
+typedef struct pubsub_multipart_callbacks_struct* pubsub_multipart_callbacks_pt;
+ 
+struct pubsub_subscriber_struct {
+    void *handle;
+     
+    /**
+     * When a new message for a topic is available the receive will be called.
+     * 
+     * msgType contains fully qualified name of the type and msgTypeId is a local id which presents the type for performance reasons.
+     * Release can be used to instruct the pubsubadmin to release (free) the message when receive function returns. Set it to false to take
+     * over ownership of the msg (e.g. take the responsibility to free it).
+     *
+     * The callbacks argument is only valid inside the receive function, use the getMultipart callback, with retain=true, to keep multipart messages in memory.
+     * results of the localMsgTypeIdForMsgType callback are valid during the complete lifecycle of the component, not just a single receive call.
+     *
+     * Return 0 implies a successful handling. If return is not 0, the msg will always be released by the pubsubadmin.
+     *
+     * this method can be  NULL.
+     */
+    int (*receive)(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, pubsub_multipart_callbacks_t *callbacks, bool *release);
+
+};
+typedef struct pubsub_subscriber_struct pubsub_subscriber_t;
+typedef struct pubsub_subscriber_struct* pubsub_subscriber_pt;
+
+
+#endif //  __PUBSUB_SUBSCRIBER_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/deploy/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/deploy/CMakeLists.txt b/celix-pubsub/pubsub/deploy/CMakeLists.txt
new file mode 100644
index 0000000..5a3838b
--- /dev/null
+++ b/celix-pubsub/pubsub/deploy/CMakeLists.txt
@@ -0,0 +1,123 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# ZMQ
+add_deploy("pubsub_zmq"
+    GROUP "pubsub"
+    BUNDLES
+       shell
+       shell_tui
+       org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+       org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+       org.apache.celix.pubsub_admin.PubSubAdmin
+       org.apache.celix.pubsub_publisher.PoiPublisher
+       org.apache.celix.pubsub_subscriber.PoiSubscriber
+)
+
+add_deploy("pubsub_publisher_zmq" 
+    GROUP "pubsub"
+    BUNDLES
+       shell
+       shell_tui
+       org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+       org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+       org.apache.celix.pubsub_admin.PubSubAdmin
+       org.apache.celix.pubsub_publisher.PoiPublisher
+       org.apache.celix.pubsub_publisher.PoiPublisher2
+   	PROPERTIES
+	    pubsub.scope=my_small_scope
+   
+)
+
+add_deploy("pubsub_subscriber_zmq"
+    GROUP "pubsub"
+    BUNDLES
+       shell
+       shell_tui
+       org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+       org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+       org.apache.celix.pubsub_admin.PubSubAdmin
+       org.apache.celix.pubsub_subscriber.PoiSubscriber
+)
+
+add_deploy("pubsub_subscriber2_zmq" 
+    GROUP "pubsub"
+    BUNDLES
+       shell
+       shell_tui
+       org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+       org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+       org.apache.celix.pubsub_admin.PubSubAdmin
+       org.apache.celix.pubsub_subscriber.PoiSubscriber
+)
+
+# UDP Multicast
+add_deploy("pubsub_publisher_udp_mc" 
+    GROUP "pubsub"
+    BUNDLES
+       shell
+       shell_tui
+       org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+       org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+       org.apache.celix.pubsub_admin.PubSubAdminUdpMc
+       org.apache.celix.pubsub_publisher.PoiPublisher
+)
+
+add_deploy("pubsub_subscriber_udp_mc" 
+    GROUP "pubsub"
+    BUNDLES
+       shell
+       shell_tui
+       org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+       org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+       org.apache.celix.pubsub_admin.PubSubAdminUdpMc
+       org.apache.celix.pubsub_subscriber.PoiSubscriber
+)
+
+add_deploy("pubsub_subscriber2_udp_mc" 
+    GROUP "pubsub"
+    BUNDLES
+       shell
+       shell_tui
+       org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+       org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+       org.apache.celix.pubsub_admin.PubSubAdminUdpMc
+       org.apache.celix.pubsub_subscriber.PoiSubscriber
+)
+
+# ZMQ Multipart
+add_deploy("pubsub_mp_subscriber_zmq" 
+    GROUP "pubsub"
+    BUNDLES
+       shell
+       shell_tui
+       org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+       org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+       org.apache.celix.pubsub_admin.PubSubAdmin
+       org.apache.celix.pubsub_subscriber.MpSubscriber
+)
+
+add_deploy("pubsub_mp_publisher_zmq" 
+    GROUP "pubsub"
+    BUNDLES
+       shell
+       shell_tui
+       org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+       org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+       org.apache.celix.pubsub_admin.PubSubAdmin
+       org.apache.celix.pubsub_publisher.MpPublisher
+)

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/CMakeLists.txt b/celix-pubsub/pubsub/examples/CMakeLists.txt
new file mode 100644
index 0000000..22ca5ca
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/CMakeLists.txt
@@ -0,0 +1,19 @@
+# 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)

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/examples/keys/README.md
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/keys/README.md b/celix-pubsub/pubsub/examples/keys/README.md
new file mode 100644
index 0000000..8517415
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/keys/README.md
@@ -0,0 +1,19 @@
+
+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/f9a5fb11/celix-pubsub/pubsub/examples/keys/publisher/private/.gitkeep
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/keys/publisher/private/.gitkeep b/celix-pubsub/pubsub/examples/keys/publisher/private/.gitkeep
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/examples/keys/publisher/public/.gitkeep
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/keys/publisher/public/.gitkeep b/celix-pubsub/pubsub/examples/keys/publisher/public/.gitkeep
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/examples/keys/subscriber/private/.gitkeep
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/keys/subscriber/private/.gitkeep b/celix-pubsub/pubsub/examples/keys/subscriber/private/.gitkeep
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/examples/keys/subscriber/public/.gitkeep
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/keys/subscriber/public/.gitkeep b/celix-pubsub/pubsub/examples/keys/subscriber/public/.gitkeep
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/CMakeLists.txt b/celix-pubsub/pubsub/examples/mp_pubsub/CMakeLists.txt
new file mode 100644
index 0000000..c828832
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/common/include/ew.h
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/common/include/ew.h b/celix-pubsub/pubsub/examples/mp_pubsub/common/include/ew.h
new file mode 100644
index 0000000..81ca5f3
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/common/include/ide.h
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/common/include/ide.h b/celix-pubsub/pubsub/examples/mp_pubsub/common/include/ide.h
new file mode 100644
index 0000000..2b9588d
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/common/include/kinematics.h
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/common/include/kinematics.h b/celix-pubsub/pubsub/examples/mp_pubsub/common/include/kinematics.h
new file mode 100644
index 0000000..5601509
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor b/celix-pubsub/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor
new file mode 100644
index 0000000..7eb8c29
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/msg_descriptors/msg_ide.descriptor
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/msg_descriptors/msg_ide.descriptor b/celix-pubsub/pubsub/examples/mp_pubsub/msg_descriptors/msg_ide.descriptor
new file mode 100644
index 0000000..f26286d
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/msg_descriptors/msg_kinematics.descriptor
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/msg_descriptors/msg_kinematics.descriptor b/celix-pubsub/pubsub/examples/mp_pubsub/msg_descriptors/msg_kinematics.descriptor
new file mode 100644
index 0000000..447b645
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt b/celix-pubsub/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
new file mode 100644
index 0000000..36c2429
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
@@ -0,0 +1,48 @@
+# 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("private/include")
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
+include_directories("${PROJECT_SOURCE_DIR}/pubsub/examples/mp_pubsub/common/include")
+
+add_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
+    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
+)
+
+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"
+)
+
+bundle_files(org.apache.celix.pubsub_publisher.MpPublisher
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher
+    DESTINATION "META-INF/keys"
+)
+
+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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h b/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h
new file mode 100644
index 0000000..a9c070f
--- /dev/null
+++ b/celix-pubsub/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 "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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c b/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
new file mode 100644
index 0000000..231157a
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
@@ -0,0 +1,150 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * 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 "pubsub_common.h"
+#include "pubsub_utils.h"
+#include "mp_publisher_private.h"
+
+#define PUB_TOPIC "multipart"
+
+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) {
+	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");
+		return CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+
+	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;
+
+	array_list_pt topic_list = pubsub_getTopicsFromString(PUB_TOPIC);
+
+	if(topic_list !=NULL){
+
+		char filter[128];
+
+		for(i=0; i<arrayList_size(topic_list);i++){
+			char* topic = arrayList_get(topic_list,i);
+			if(strlen(topic)<MAX_TOPIC_LEN){
+
+				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);
+			}
+			else{
+				printf("Topic %s too long. Skipping publication.\n",topic);
+			}
+			free(topic);
+		}
+		arrayList_destroy(topic_list);
+
+	}
+
+	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;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c b/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
new file mode 100644
index 0000000..851d9c1
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
@@ -0,0 +1,161 @@
+/**
+ *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 "pubsub_common.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)rand()) / (((double)RAND_MAX)/(max-min))) ;
+	return ret;
+}
+
+static unsigned int randInt(unsigned int min, unsigned int max){
+	double scaled = ((double)rand())/((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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt b/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
new file mode 100644
index 0000000..503a708
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
@@ -0,0 +1,48 @@
+# 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("private/include")
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
+include_directories("${PROJECT_SOURCE_DIR}/pubsub/examples/mp_pubsub/common/include")
+
+add_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
+		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
+)
+
+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"
+)
+
+bundle_files(org.apache.celix.pubsub_subscriber.MpSubscriber
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber
+    DESTINATION "META-INF/keys"
+)
+
+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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h b/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h
new file mode 100644
index 0000000..1cc7270
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/include/mp_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.
+ */
+/*
+ * 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_common.h"
+#include "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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c b/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
new file mode 100644
index 0000000..ecd4245
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
@@ -0,0 +1,117 @@
+/**
+ *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 "bundle_activator.h"
+
+#include "pubsub_common.h"
+#include "pubsub_utils.h"
+#include "mp_subscriber_private.h"
+
+#define SUB_TOPIC "multipart"
+
+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_TOPIC);
+	subsvc->handle = sub;
+	subsvc->receive = pubsub_subscriber_recv;
+
+	act->subsvc = subsvc;
+
+	array_list_pt topic_list = pubsub_getTopicsFromString(SUB_TOPIC);
+
+	if(topic_list !=NULL){
+
+		int i;
+		for(i=0; i<arrayList_size(topic_list);i++){
+			char* topic = arrayList_get(topic_list,i);
+			if(strlen(topic)<MAX_TOPIC_LEN){
+				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);
+			}
+			else{
+				printf("Topic %s too long. Skipping subscription.\n",topic);
+			}
+			free(topic);
+		}
+		arrayList_destroy(topic_list);
+
+	}
+
+	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/f9a5fb11/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/src/mp_subscriber.c
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/src/mp_subscriber.c b/celix-pubsub/pubsub/examples/mp_pubsub/subscriber/private/src/mp_subscriber.c
new file mode 100644
index 0000000..a5ad03a
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/pubsub/CMakeLists.txt b/celix-pubsub/pubsub/examples/pubsub/CMakeLists.txt
new file mode 100644
index 0000000..73b3e52
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/pubsub/common/include/poi.h
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/pubsub/common/include/poi.h b/celix-pubsub/pubsub/examples/pubsub/common/include/poi.h
new file mode 100644
index 0000000..7bb077e
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor b/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
new file mode 100644
index 0000000..e547b62
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor b/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
new file mode 100644
index 0000000..0c369b5
--- /dev/null
+++ b/celix-pubsub/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/f9a5fb11/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/poi1.properties
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/poi1.properties b/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/poi1.properties
new file mode 100644
index 0000000..bd06c13
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/poi1.properties
@@ -0,0 +1,18 @@
+#
+# included in the bundle at location META-INF/topics/[pub|sub]/poi2.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/f9a5fb11/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/poi2.properties
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/poi2.properties b/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/poi2.properties
new file mode 100644
index 0000000..2edbdf6
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/pubsub/msg_descriptors/poi2.properties
@@ -0,0 +1,18 @@
+#
+# 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/f9a5fb11/celix-pubsub/pubsub/examples/pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/pubsub/publisher/CMakeLists.txt b/celix-pubsub/pubsub/examples/pubsub/publisher/CMakeLists.txt
new file mode 100644
index 0000000..4a5feda
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/pubsub/publisher/CMakeLists.txt
@@ -0,0 +1,52 @@
+# 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("private/include")
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
+
+add_bundle(org.apache.celix.pubsub_publisher.PoiPublisher
+    SYMBOLIC_NAME "apache_celix_pubsub_poi_publisher"
+    VERSION "1.0.0"
+    SOURCES 
+    	private/src/ps_pub_activator.c
+    	private/src/pubsub_publisher.c
+    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c	
+)
+
+bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
+		${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"
+)
+
+bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
+		${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"
+)
+
+bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher
+    DESTINATION "META-INF/keys"
+)
+
+bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
+		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber/public
+    DESTINATION "META-INF/keys/subscriber"
+)

http://git-wip-us.apache.org/repos/asf/celix/blob/f9a5fb11/celix-pubsub/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h b/celix-pubsub/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h
new file mode 100644
index 0000000..834dada
--- /dev/null
+++ b/celix-pubsub/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 "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/f9a5fb11/celix-pubsub/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
----------------------------------------------------------------------
diff --git a/celix-pubsub/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c b/celix-pubsub/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
new file mode 100644
index 0000000..e4a8ba8
--- /dev/null
+++ b/celix-pubsub/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
@@ -0,0 +1,157 @@
+/**
+ *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_common.h"
+#include "pubsub_utils.h"
+#include "publisher.h"
+#include "pubsub_publisher_private.h"
+
+#define PUB_TOPIC "poi1;poi2"
+
+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) {
+	struct publisherActivator * act = malloc(sizeof(*act));
+
+	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;
+	}
+
+	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;
+	array_list_pt topic_list = pubsub_getTopicsFromString(PUB_TOPIC);
+
+	if(topic_list !=NULL){
+
+		char filter[128];
+		for(i=0; i<arrayList_size(topic_list);i++){
+			char* topic = arrayList_get(topic_list,i);
+			if(strlen(topic)<MAX_TOPIC_LEN){
+
+				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);
+			}
+			else{
+				printf("Topic %s too long. Skipping publication.\n",topic);
+			}
+			free(topic);
+		}
+		arrayList_destroy(topic_list);
+
+	}
+
+	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;
+}