You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by ab...@apache.org on 2014/01/07 11:33:56 UTC

svn commit: r1556172 [1/2] - in /incubator/celix/trunk: remote_services/ remote_services/discovery_shm/ remote_services/discovery_shm/private/ remote_services/discovery_shm/private/include/ remote_services/discovery_shm/private/src/ remote_services/rem...

Author: abroekhuis
Date: Tue Jan  7 10:33:55 2014
New Revision: 1556172

URL: http://svn.apache.org/r1556172
Log:
CELIX-81, CELIX-80: Applied patch for Shared Memory RSA. Updated constant usage to use the new prefix format.

Added:
    incubator/celix/trunk/remote_services/discovery_shm/
    incubator/celix/trunk/remote_services/discovery_shm/CMakeLists.txt
    incubator/celix/trunk/remote_services/discovery_shm/private/
    incubator/celix/trunk/remote_services/discovery_shm/private/include/
    incubator/celix/trunk/remote_services/discovery_shm/private/include/discovery.h
    incubator/celix/trunk/remote_services/discovery_shm/private/src/
    incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery.c
    incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery_activator.c
    incubator/celix/trunk/remote_services/remote_service_admin_shm/
    incubator/celix/trunk/remote_services/remote_service_admin_shm/CMakeLists.txt
    incubator/celix/trunk/remote_services/remote_service_admin_shm/private/
    incubator/celix/trunk/remote_services/remote_service_admin_shm/private/include/
    incubator/celix/trunk/remote_services/remote_service_admin_shm/private/include/remote_service_admin_shm_impl.h
    incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/
    incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/export_registration_impl.c
    incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/import_registration_impl.c
    incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_activator.c
    incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c
    incubator/celix/trunk/remote_services/remote_service_admin_shm/public/
    incubator/celix/trunk/remote_services/remote_service_admin_shm/public/include/
    incubator/celix/trunk/remote_services/remote_service_admin_shm/public/include/remote_service_admin_shm.h
    incubator/celix/trunk/utils/private/src/netstring.c
    incubator/celix/trunk/utils/private/test/netstring_test.c
    incubator/celix/trunk/utils/public/include/netstring.h
Modified:
    incubator/celix/trunk/remote_services/CMakeLists.txt
    incubator/celix/trunk/remote_services/deploy.cmake
    incubator/celix/trunk/utils/CMakeLists.txt

Modified: incubator/celix/trunk/remote_services/CMakeLists.txt
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/CMakeLists.txt?rev=1556172&r1=1556171&r2=1556172&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/CMakeLists.txt (original)
+++ incubator/celix/trunk/remote_services/CMakeLists.txt Tue Jan  7 10:33:55 2014
@@ -32,8 +32,10 @@ if (REMOTE_SERVICE_ADMIN)
     add_subdirectory(topology_manager)
     add_subdirectory(remote_service_admin)
     add_subdirectory(remote_service_admin_http)
+    add_subdirectory(remote_service_admin_shm)   
     add_subdirectory(discovery_slp)
     add_subdirectory(discovery_bonjour)
+    add_subdirectory(discovery_shm)
     
     add_subdirectory(calculator_service)
     add_subdirectory(calculator_endpoint)

Modified: incubator/celix/trunk/remote_services/deploy.cmake
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/deploy.cmake?rev=1556172&r1=1556171&r2=1556172&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/deploy.cmake (original)
+++ incubator/celix/trunk/remote_services/deploy.cmake Tue Jan  7 10:33:55 2014
@@ -20,7 +20,7 @@ if (REMOTE_SERVICE_ADMIN)
 	                            ENDPOINTS org.example.api.Calculator_endpoint)
 	deploy("remote-services-bj-client" BUNDLES topology_manager remote_service_admin_http shell shell_tui log_service log_writer calculator_shell discovery_bonjour
 	                                   ENDPOINTS org.example.api.Calculator_proxy)
-	
+	                                   
 	deploy("remote-services" BUNDLES discovery_slp topology_manager remote_service_admin_http calculator org.example.api.Calculator_endpoint shell shell_tui log_service log_writer)
 	deploy("remote-services-client" BUNDLES topology_manager remote_service_admin_http org.example.api.Calculator_proxy shell shell_tui log_service log_writer calculator_shell discovery_slp)
 	
@@ -28,3 +28,14 @@ if (REMOTE_SERVICE_ADMIN)
 	#discovery will discover services before the topology manager is registered as 
 	#endpoint listener and services will be lost. This needs further study.
 endif (REMOTE_SERVICE_ADMIN)
+
+is_enabled(RSA_BUNDLES_REMOTE_SERVICE_ADMIN_SHM)
+if (RSA_BUNDLES_REMOTE_SERVICE_ADMIN_SHM)
+    is_enabled(RSA_BUNDLES_DISCOVERY_SHM)
+    if (RSA_BUNDLES_DISCOVERY_SHM)
+        deploy("remote-services-shm" BUNDLES discovery_shm topology_manager remote_service_admin_shm calculator shell shell_tui log_service log_writer 
+                                     ENDPOINTS org.example.api.Calculator_endpoint)
+        deploy("remote-services-shm-client" BUNDLES topology_manager remote_service_admin_shm shell shell_tui log_service log_writer calculator_shell discovery_shm
+                                            ENDPOINTS org.example.api.Calculator_proxy)
+    endif (RSA_BUNDLES_DISCOVERY_SHM)
+endif (RSA_BUNDLES_REMOTE_SERVICE_ADMIN_SHM)

Added: incubator/celix/trunk/remote_services/discovery_shm/CMakeLists.txt
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/discovery_shm/CMakeLists.txt?rev=1556172&view=auto
==============================================================================
--- incubator/celix/trunk/remote_services/discovery_shm/CMakeLists.txt (added)
+++ incubator/celix/trunk/remote_services/discovery_shm/CMakeLists.txt Tue Jan  7 10:33:55 2014
@@ -0,0 +1,39 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+celix_subproject(RSA_BUNDLES_DISCOVERY_SHM "Option to enable building the Discovery (SHM) bundle" ON DEPS LAUNCHER topology_manager remote_service_admin)
+if (RSA_BUNDLES_DISCOVERY_SHM)
+	include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery_shm/private/include")
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_shm/public/include")
+	include_directories("private/include")
+
+	SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_rsa_discovery_shm")
+	SET_HEADERS("Bundle-Name: Apache Celix RSA Discovery SHM")
+
+	bundle(discovery_shm SOURCES 
+		private/src/discovery 
+		private/src/discovery_activator
+	)
+
+	install_bundle(discovery_shm)
+		
+	target_link_libraries(discovery_shm celix_framework ${APRUTIL_LIBRARY})
+
+endif (RSA_BUNDLES_DISCOVERY_SHM)

Added: incubator/celix/trunk/remote_services/discovery_shm/private/include/discovery.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/discovery_shm/private/include/discovery.h?rev=1556172&view=auto
==============================================================================
--- incubator/celix/trunk/remote_services/discovery_shm/private/include/discovery.h (added)
+++ incubator/celix/trunk/remote_services/discovery_shm/private/include/discovery.h Tue Jan  7 10:33:55 2014
@@ -0,0 +1,63 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * discovery.h
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef DISCOVERY_H_
+#define DISCOVERY_H_
+
+#define DISCOVERY_SHM_MEMSIZE 32768
+#define DISCOVERY_SHM_FILENAME "/dev/null"
+#define DISCOVERY_SHM_FTOK_ID 50
+#define DISCOVERY_SEM_FILENAME "/dev/null"
+#define DISCOVERY_SEM_FTOK_ID 52
+
+#include "endpoint_listener.h"
+
+
+struct ipc_shmData
+{
+	int semId;
+	int numListeners;
+	char data[DISCOVERY_SHM_MEMSIZE - (2* (sizeof(int) + sizeof(key_t)))];
+};
+
+typedef struct discovery *discovery_pt;
+typedef struct ipc_shmData *ipc_shmData_pt;
+
+celix_status_t discovery_create(apr_pool_t *pool, bundle_context_pt context, discovery_pt *discovery);
+celix_status_t discovery_stop(discovery_pt discovery);
+
+celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+
+celix_status_t discovery_endpointListenerAdding(void * handle, service_reference_pt reference, void **service);
+celix_status_t discovery_endpointListenerAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service);
+celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service);
+
+celix_status_t discovery_updateEndpointListener(discovery_pt discovery, service_reference_pt reference, endpoint_listener_pt service);
+
+
+#endif /* DISCOVERY_H_ */

Added: incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery.c?rev=1556172&view=auto
==============================================================================
--- incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery.c (added)
+++ incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery.c Tue Jan  7 10:33:55 2014
@@ -0,0 +1,751 @@
+
+
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * discovery.c
+ *
+ *  \date       Oct 4, 2011
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <apr_strings.h>
+
+#include <sys/types.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+
+#include "bundle_context.h"
+#include "array_list.h"
+#include "utils.h"
+#include "celix_errno.h"
+#include "filter.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "netstring.h"
+
+#include "discovery.h"
+
+struct discovery {
+	bundle_context_pt context;
+	apr_pool_t *pool;
+
+	hash_map_pt listenerReferences;
+
+	bool running;
+
+	int  shmId;
+	void *shmBaseAdress;
+	apr_thread_t *shmPollThread;
+
+	hash_map_pt shmServices;
+
+	array_list_pt handled;
+	array_list_pt registered;
+};
+
+celix_status_t discovery_informListener(discovery_pt discovery, endpoint_listener_pt listener, endpoint_description_pt endpoint);
+celix_status_t discovery_informListenerOfRemoval(discovery_pt discovery, endpoint_listener_pt listener, endpoint_description_pt endpoint);
+
+celix_status_t discovery_addService(discovery_pt discovery, endpoint_description_pt endpoint);
+celix_status_t discovery_removeService(discovery_pt discovery, endpoint_description_pt endpoint);
+
+static void *APR_THREAD_FUNC discovery_pollSHMServices(apr_thread_t *thd, void *data);
+celix_status_t discovery_lock(int semId, int semNr);
+celix_status_t discovery_unlock(int semId, int semNr);
+celix_status_t discovery_wait(int semId, int semNr);
+
+celix_status_t discovery_updateLocalSHMServices(discovery_pt discovery);
+celix_status_t discovery_updateSHMServices(discovery_pt discovery, char *serviceName, char *nsEncAttributes);
+
+celix_status_t discovery_registerSHMService(discovery_pt discovery, char *url, char *attributes);
+celix_status_t discovery_deregisterSHMService(discovery_pt discovery, char *serviceName);
+celix_status_t discovery_createOrAttachShm(discovery_pt discovery);
+celix_status_t discovery_stopOrDetachShm(discovery_pt discovery);
+
+celix_status_t discovery_create(apr_pool_t *pool, bundle_context_pt context, discovery_pt *discovery) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("DISCOVERY started.\n");
+
+	*discovery = apr_palloc(pool, sizeof(**discovery));
+	if (!*discovery) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*discovery)->context = context;
+		(*discovery)->pool = pool;
+		(*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+		(*discovery)->shmServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+		(*discovery)->running = true;
+		(*discovery)->handled = NULL;
+		arrayList_create(&(*discovery)->handled);
+		(*discovery)->registered = NULL;
+		arrayList_create(&(*discovery)->registered);
+
+		(*discovery)->shmId = -1;
+		(*discovery)->shmBaseAdress = NULL;
+
+		if ((status = discovery_createOrAttachShm(*discovery)) != CELIX_SUCCESS)
+		{
+			printf("DISCOVERY: Shared Memory initialization failed.\n");
+		}
+		else
+		{
+			apr_thread_create(&(*discovery)->shmPollThread, NULL, discovery_pollSHMServices, *discovery, (*discovery)->pool);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t discovery_stop(discovery_pt discovery) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	apr_status_t tstat;
+	discovery->running = false;
+
+	ipc_shmData_pt shmData = (ipc_shmData_pt) discovery->shmBaseAdress;
+
+	if (shmData != NULL)
+	{
+		discovery_unlock(shmData->semId, 1);
+		discovery_wait(shmData->semId, 2);
+		discovery_lock(shmData->semId, 1);
+
+		apr_status_t stat = apr_thread_join(&tstat, discovery->shmPollThread);
+
+		if (stat != APR_SUCCESS && tstat != APR_SUCCESS)
+		{
+			printf("DISCOVERY: An error occured while stopping the SHM polling thread.\n");
+			status = CELIX_BUNDLE_EXCEPTION;
+		}
+		else
+		{
+			printf("DISCOVERY: SHM polling thread sucessfully stopped.\n");
+			int i;
+			for (i = 0; i < arrayList_size(discovery->registered); i++) {
+				char *serviceName = arrayList_get(discovery->registered, i);
+				printf("DISCOVERY: deregistering service %s.\n", serviceName);
+				status = discovery_deregisterSHMService(discovery, serviceName);
+			}
+
+			//discovery_lock(shmData->semId, 1);
+
+			// detach from shm
+			status = discovery_stopOrDetachShm(discovery);
+
+		}
+	}
+
+	return status;
+}
+
+celix_status_t discovery_removeService(discovery_pt discovery, endpoint_description_pt endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+	printf("DISCOVERY: Remove service (%s)\n", endpoint->service);
+
+	// Inform listeners of new endpoint
+	hash_map_iterator_pt iter = hashMapIterator_create(discovery->listenerReferences);
+	while (hashMapIterator_hasNext(iter)) {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		service_reference_pt reference = hashMapEntry_getKey(entry);
+		endpoint_listener_pt listener = NULL;
+		bundleContext_getService(discovery->context, reference, (void**)&listener);
+		discovery_informListenerOfRemoval(discovery, listener, endpoint);
+	}
+
+	return status;
+}
+
+celix_status_t discovery_addService(discovery_pt discovery, endpoint_description_pt endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	// Inform listeners of new endpoint
+	hash_map_iterator_pt iter = hashMapIterator_create(discovery->listenerReferences);
+
+	printf("DISCOVERY: Add service (%s)\n", endpoint->service);
+
+
+	while (hashMapIterator_hasNext(iter)) {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		service_reference_pt reference = hashMapEntry_getKey(entry);
+		endpoint_listener_pt listener = NULL;
+
+		service_registration_pt registration = NULL;
+		serviceReference_getServiceRegistration(reference, &registration);
+		properties_pt serviceProperties = NULL;
+		serviceRegistration_getProperties(registration, &serviceProperties);
+		char *scope = properties_get(serviceProperties, (char *) OSGI_ENDPOINT_LISTENER_SCOPE);
+		filter_pt filter = filter_create(scope, discovery->pool);
+		bool matchResult = false;
+		filter_match(filter, endpoint->properties, &matchResult);
+		if (matchResult) {
+			printf("DISCOVERY: Add service (%s)\n", endpoint->service);
+			bundleContext_getService(discovery->context, reference, (void**)&listener);
+			discovery_informListener(discovery, listener, endpoint);
+		}
+	}
+
+	return status;
+}
+
+
+
+celix_status_t discovery_informListener(discovery_pt discovery, endpoint_listener_pt listener, endpoint_description_pt endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	listener->endpointAdded(listener->handle, endpoint, NULL);
+	return status;
+}
+
+celix_status_t discovery_informListenerOfRemoval(discovery_pt discovery, endpoint_listener_pt listener, endpoint_description_pt endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+	listener->endpointRemoved(listener->handle, endpoint, NULL);
+	return status;
+}
+
+
+celix_status_t discovery_lock(int semId, int semNr)
+{
+	celix_status_t status = CELIX_SUCCESS;
+	int semOpStatus = 0;
+	struct sembuf semOperation;
+
+	semOperation.sem_num=semNr;
+	semOperation.sem_op=-1;
+	semOperation.sem_flg=0;
+
+	do
+	{
+		status = CELIX_SUCCESS;
+
+		if ((semOpStatus = semop(semId, &semOperation, 1)) != 0)
+		{
+			status = CELIX_BUNDLE_EXCEPTION;
+		}
+	} while(semOpStatus == -1 && errno == EINTR);
+
+	return status;
+}
+
+
+celix_status_t discovery_unlock(int semId, int semNr)
+{
+	celix_status_t status = CELIX_SUCCESS;
+	int semOpStatus = 0;
+	struct sembuf semOperation;
+
+	semOperation.sem_num=semNr;
+	semOperation.sem_op=1;
+	semOperation.sem_flg=0;
+
+	do
+	{
+		status = CELIX_SUCCESS;
+
+		if ((semOpStatus = semop(semId, &semOperation, 1)) != 0)
+		{
+			status = CELIX_BUNDLE_EXCEPTION;
+		}
+	} while(semOpStatus == -1 && errno == EINTR);
+
+
+	return status;
+}
+
+
+celix_status_t discovery_wait(int semId, int semNr)
+{
+    celix_status_t status = CELIX_SUCCESS;
+    int semOpStatus = 0;
+    struct sembuf semOperation;
+
+    semOperation.sem_num = semNr;
+    semOperation.sem_op = 0;
+    semOperation.sem_flg = 0;
+
+    do
+    {
+        status = CELIX_SUCCESS;
+
+        if ((semOpStatus = semop(semId, &semOperation, 1)) != 0)
+        {
+            status = CELIX_BUNDLE_EXCEPTION;
+        }
+    } while (semOpStatus == -1 && errno == EINTR);
+
+    return status;
+}
+
+
+
+celix_status_t discovery_updateSHMServices(discovery_pt discovery, char *serviceName, char *nsEncAttributes)
+{
+	celix_status_t status = CELIX_SUCCESS;
+
+	if ((discovery->shmId  < 0) || (discovery->shmBaseAdress == NULL))
+	{
+		printf("DISCOVERY : shared memory not initialized.\n");
+		status = CELIX_BUNDLE_EXCEPTION;
+	}
+	else
+	{
+   		ipc_shmData_pt shmData = (ipc_shmData_pt) discovery->shmBaseAdress;
+
+		if((status = discovery_lock(shmData->semId, 0)) == CELIX_SUCCESS)
+		{
+			hash_map_pt registeredShmServices = hashMap_create(utils_stringHash, utils_stringHash, utils_stringEquals, utils_stringEquals);
+
+			/* get already saved properties */
+			if ((status = netstring_decodeToHashMap(discovery->pool, shmData->data, registeredShmServices)) != CELIX_SUCCESS)
+			{
+				printf("DISCOVERY : discovery_registerSHMService : decoding data to Properties failed\n");
+			}
+			else
+			{
+				char *encShmServices = NULL;
+
+				if (nsEncAttributes != NULL)
+				{
+					hashMap_put(registeredShmServices, serviceName, nsEncAttributes);
+				}
+				else
+				{
+					hashMap_remove(registeredShmServices, serviceName);
+				}
+
+				// write back
+				if ((status = netstring_encodeFromHashMap(discovery->pool, registeredShmServices, &encShmServices)) == CELIX_SUCCESS)
+				{
+					strcpy(shmData->data, encShmServices);
+				}
+				else
+				{
+					printf("DISCOVERY : discovery_registerSHMService : encoding data from HashMap failed\n");
+				}
+			}
+
+			hashMap_destroy(registeredShmServices, false, false);
+			discovery_unlock(shmData->semId, 0);
+
+			/* unlock and afterwards lock to inform all listener */
+			discovery_unlock(shmData->semId, 1);
+			// wait till notify semaphore is 0 to ensure all threads have performed update routine
+			discovery_wait(shmData->semId, 2);
+			discovery_lock(shmData->semId, 1);
+		}
+	}
+	return status;
+}
+
+
+celix_status_t discovery_registerSHMService(discovery_pt discovery, char *serviceName, char *nsEncAttributes)
+{
+	return discovery_updateSHMServices(discovery, serviceName, nsEncAttributes);
+}
+
+
+
+celix_status_t discovery_deregisterSHMService(discovery_pt discovery, char *serviceName)
+{
+	return discovery_updateSHMServices(discovery, serviceName, NULL);
+}
+
+
+
+
+celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *machtedFilter) {
+	celix_status_t status = CELIX_SUCCESS;
+	printf("DISCOVERY: Endpoint for %s, with filter \"%s\" added\n", endpoint->service, machtedFilter);
+	discovery_pt discovery = handle;
+
+	if (status == CELIX_SUCCESS) {
+
+		char *nsEncAttribute;
+
+		netstring_encodeFromHashMap(discovery->pool, (hash_map_pt) endpoint->properties, &nsEncAttribute);
+
+		if ((status = discovery_registerSHMService(discovery, endpoint->service, nsEncAttribute)) != CELIX_SUCCESS)
+		{
+			printf("DISCOVERY: Error registering service (%s) within shared memory \n", endpoint->service);
+		}
+
+		arrayList_add(discovery->registered, strdup(endpoint->service));
+	}
+
+	return status;
+}
+
+
+celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *machtedFilter) {
+	celix_status_t status = CELIX_SUCCESS;
+	printf("DISCOVERY: Endpoint for %s, with filter \"%s\" removed\n", endpoint->service, machtedFilter);
+
+	discovery_pt discovery = handle;
+	char *serviceUrl = NULL;
+
+	if (status == CELIX_SUCCESS) {
+		status = discovery_deregisterSHMService(discovery, endpoint->service);
+		int i;
+		for (i = 0; i < arrayList_size(discovery->registered); i++) {
+			char *url = arrayList_get(discovery->registered, i);
+			if (strcmp(url, endpoint->service) == 0) {
+				arrayList_remove(discovery->registered, i);
+			}
+		}
+	}
+
+	return status;
+}
+
+celix_status_t discovery_endpointListenerAdding(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	discovery_pt discovery = handle;
+
+	bundleContext_getService(discovery->context, reference, service);
+
+	return status;
+}
+
+celix_status_t discovery_endpointListenerAdded(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	discovery_pt discovery = handle;
+
+	service_registration_pt registration = NULL;
+	serviceReference_getServiceRegistration(reference, &registration);
+	properties_pt serviceProperties = NULL;
+	serviceRegistration_getProperties(registration, &serviceProperties);
+	char *discoveryListener = properties_get(serviceProperties, "DISCOVERY");
+
+	if (discoveryListener != NULL && strcmp(discoveryListener, "true") == 0) {
+		printf("DISCOVERY: EndpointListener Ignored - Discovery listener\n");
+	} else {
+		discovery_updateEndpointListener(discovery, reference, (endpoint_listener_pt) service);
+	}
+
+	return status;
+}
+
+celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	discovery_pt discovery = handle;
+
+	discovery_updateEndpointListener(discovery, reference, (endpoint_listener_pt) service);
+
+	return status;
+}
+
+celix_status_t discovery_updateEndpointListener(discovery_pt discovery, service_reference_pt reference, endpoint_listener_pt service) {
+	celix_status_t status = CELIX_SUCCESS;
+	char *scope = "createScopeHere";
+
+	array_list_pt scopes = hashMap_get(discovery->listenerReferences, reference);
+	if (scopes == NULL) {
+		scopes = NULL;
+		arrayList_create(&scopes);
+		hashMap_put(discovery->listenerReferences, reference, scopes);
+	}
+
+	if (!arrayList_contains(scopes, scope)) {
+		arrayList_add(scopes, scope);
+	}
+
+	hash_map_iterator_pt iter = hashMapIterator_create(discovery->shmServices);
+
+	while (hashMapIterator_hasNext(iter)) {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		char *key = hashMapEntry_getKey(entry);
+		endpoint_description_pt value = hashMapEntry_getValue(entry);
+		discovery_informListener(discovery, service, value);
+	}
+
+	return status;
+}
+
+celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	discovery_pt discovery = handle;
+
+	printf("DISCOVERY: EndpointListener Removed\n");
+	hashMap_remove(discovery->listenerReferences, reference);
+
+	return status;
+}
+
+
+celix_status_t discovery_createOrAttachShm(discovery_pt discovery)
+{
+	celix_status_t status = CELIX_SUCCESS;
+
+	key_t shmKey = ftok(DISCOVERY_SHM_FILENAME,  DISCOVERY_SHM_FTOK_ID);
+
+	if ((discovery->shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, 0666)) < 0)
+	{
+	   	printf("DISCOVERY : Could not attach to shared memory. Trying to create shared memory segment. \n");
+
+	   	// trying to create shared memory
+	   	if ((discovery->shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, IPC_CREAT | 0666)) < 0)
+	   	{
+	   		printf("DISCOVERY : Creation of shared memory segment failed\n");
+	   		status = CELIX_BUNDLE_EXCEPTION;
+	   	}
+	   	else if ((discovery->shmBaseAdress = shmat(discovery->shmId, 0, 0)) == (char*) -1 )
+	   	{
+	   		printf("DISCOVERY : Attaching of shared memory segment failed\n");
+	   		status = CELIX_BUNDLE_EXCEPTION;
+	   	}
+	   	else
+	   	{
+	   		int semId = -1;
+	   		key_t semKey = -1;
+	   		ipc_shmData_pt shmData = NULL;
+	   		printf("DISCOVERY : Shared memory segment successfully created at %p\n", discovery->shmBaseAdress);
+
+	   		// create structure
+	   		shmData = apr_palloc(discovery->pool, sizeof(*shmData));
+   			semKey = ftok(DISCOVERY_SEM_FILENAME, DISCOVERY_SEM_FTOK_ID);
+
+			if ((semId = semget(semKey, 3, 0666 | IPC_CREAT)) == -1)
+			{
+				printf("DISCOVERY : Creation of semaphores failed %i\n", semId);
+			}
+			else
+			{
+				// set
+				if ( semctl (semId, 0, SETVAL, (int) 1) < 0)
+				{
+					printf(" DISCOVERY : error while initializing semaphore 0 \n");
+				}
+				else
+				{
+					printf(" DISCOVERY : semaphore 0 initialized w/ %d\n", semctl(semId, 0, GETVAL, 0));
+				}
+
+				if ( semctl (semId, 1, SETVAL, (int) 0) < 0)
+				{
+					printf(" DISCOVERY : error while initializing semaphore 1\n");
+				}
+				else
+				{
+					printf(" DISCOVERY : semaphore 1 initialized w/ %d\n", semctl(semId, 1, GETVAL, 0));
+				}
+
+				if ( semctl (semId, 2, SETVAL, (int) 0) < 0)
+				{
+					printf(" DISCOVERY : error while initializing semaphore 2\n");
+				}
+				else
+				{
+					printf(" DISCOVERY : semaphore 2 initialized w/ %d\n", semctl(semId, 2, GETVAL, 0));
+				}
+
+				shmData->semId = semId;
+				memcpy(discovery->shmBaseAdress, shmData, sizeof(*shmData));
+			}
+	   	}
+	}
+   	else if ((discovery->shmBaseAdress = shmat(discovery->shmId, 0, 0)) < 0)
+   	{
+   		printf("DISCOVERY : Attaching of shared memory segment failed\n");
+   		status = CELIX_BUNDLE_EXCEPTION;
+   	}
+   	else
+	{
+   		ipc_shmData_pt shmData = (ipc_shmData_pt) discovery->shmBaseAdress;
+
+		discovery_lock(shmData->semId, 0);
+   		shmData->numListeners++;
+		discovery_unlock(shmData->semId, 0);
+		discovery_updateLocalSHMServices(discovery);
+	}
+
+	return status;
+}
+
+
+
+celix_status_t discovery_stopOrDetachShm(discovery_pt discovery)
+{
+	celix_status_t status = CELIX_SUCCESS;
+
+	if ((discovery->shmId  < 0) || (discovery->shmBaseAdress == NULL))
+	{
+		printf("DISCOVERY : discovery_addNewEntry : shared memory not initialized.\n");
+		status = CELIX_BUNDLE_EXCEPTION;
+	}
+	else
+	{
+		int listener = 0;
+   		ipc_shmData_pt shmData = (ipc_shmData_pt) discovery->shmBaseAdress;
+
+		discovery_lock(shmData->semId, 0);
+		listener = shmData->numListeners--;
+		discovery_unlock(shmData->semId, 0);
+
+		if (listener  > 0)
+		{
+			printf("DISCOVERY: Detaching from Shared memory\n");
+			shmdt(discovery->shmBaseAdress);
+		}
+		else
+		{
+			printf("DISCOVERY: Removing semaphore w/ id \n");
+			ipc_shmData_pt shmData = (ipc_shmData_pt) discovery->shmBaseAdress;
+			semctl(shmData->semId, 0, IPC_RMID);
+			printf("DISCOVERY: Detaching from Shared memory\n");
+			shmdt(discovery->shmBaseAdress);
+			printf("DISCOVERY: Destroying Shared memory\n");
+			shmctl(discovery->shmId, IPC_RMID, 0);
+		}
+	}
+
+	return status;
+}
+
+
+celix_status_t discovery_updateLocalSHMServices(discovery_pt discovery)
+{
+	celix_status_t status = CELIX_SUCCESS;
+	ipc_shmData_pt shmData = (ipc_shmData_pt) discovery->shmBaseAdress;
+
+	if((status = discovery_lock(shmData->semId, 0)) != CELIX_SUCCESS)
+	{
+		printf("DISCOVERY : discovery_updateLocalSHMServices : cannot acquire semaphore\n");
+	}
+	else
+	{
+		hash_map_pt registeredShmServices = hashMap_create(utils_stringHash, utils_stringHash, utils_stringEquals, utils_stringEquals);
+
+		if ((status = netstring_decodeToHashMap(discovery->pool, &(shmData->data[0]), registeredShmServices)) != CELIX_SUCCESS)
+		{
+			printf("DISCOVERY : discovery_updateLocalSHMServices : decoding data to properties failed\n");
+		}
+		else
+		{
+			/* check for new services */
+			hash_map_iterator_pt shmPrpItr = hashMapIterator_create(registeredShmServices);
+
+			while(hashMapIterator_hasNext(shmPrpItr) == true)
+			{
+				hash_map_entry_pt shmPrpEntry = hashMapIterator_nextEntry(shmPrpItr);
+				char *serviceName = hashMapEntry_getKey(shmPrpEntry);
+
+				if(hashMap_get(discovery->shmServices, serviceName) != NULL)
+				{
+					printf("DISCOVERY : discovery_updateLocalSHMServices : service with url %s already registered\n", serviceName );
+				}
+				else
+				{
+					hash_map_pt props = hashMap_create(utils_stringHash, utils_stringHash, utils_stringEquals, utils_stringEquals);
+					char *nsEncEndpointProp = hashMapEntry_getValue(shmPrpEntry);
+
+					if ( (status = netstring_decodeToHashMap(discovery->pool, nsEncEndpointProp, props)) != CELIX_SUCCESS)
+					{
+						printf("DISCOVERY : discovery_updateLocalSHMServices : Decoding of endpointProperties failed\n");
+					}
+					else
+					{
+						endpoint_description_pt endpoint = apr_palloc(discovery->pool, sizeof(*endpoint));
+						endpoint->id = apr_pstrdup(discovery->pool, serviceName);
+						endpoint->serviceId = 42;
+						endpoint->service = apr_pstrdup(discovery->pool, serviceName);
+						endpoint->properties = (properties_pt) props;
+
+						discovery_addService(discovery, endpoint);
+						hashMap_put(discovery->shmServices, apr_pstrdup(discovery->pool, serviceName), endpoint);
+					}
+				}
+			}
+
+			hashMapIterator_destroy(shmPrpItr);
+
+			/* check for obsolete services */
+			hash_map_iterator_pt shmServicesItr = hashMapIterator_create(discovery->shmServices);
+
+			while(hashMapIterator_hasNext(shmServicesItr) == true)
+			{
+				hash_map_entry_pt shmService = hashMapIterator_nextEntry(shmServicesItr);
+				char *url = hashMapEntry_getKey(shmService);
+
+				if(hashMap_get(registeredShmServices, url) == NULL)
+				{
+					printf("DISCOVERY : discovery_updateLocalSHMServices : service with url %s unregistered\n", url);
+					endpoint_description_pt endpoint =  hashMap_get(discovery->shmServices, url);
+					discovery_removeService(discovery, endpoint);
+					hashMap_remove(discovery->shmServices, url);
+				}
+			}
+			hashMapIterator_destroy(shmServicesItr);
+		}
+
+		discovery_unlock(shmData->semId, 0);
+		hashMap_destroy(registeredShmServices, false, false);
+	}
+	return status;
+}
+
+
+static void *APR_THREAD_FUNC discovery_pollSHMServices(apr_thread_t *thd, void *data)
+{
+	discovery_pt discovery = data;
+	celix_status_t status = CELIX_SUCCESS;
+
+	if ((discovery->shmId  < 0) || (discovery->shmBaseAdress == NULL))
+	{
+		printf("DISCOVERY : discovery_pollSHMServices : shared memory not initialized.\n");
+		status = CELIX_BUNDLE_EXCEPTION;
+	}
+	else
+	{
+   		ipc_shmData_pt shmData = (ipc_shmData_pt) discovery->shmBaseAdress;
+
+		printf("DISCOVERY : discovery_pollSHMServices thread started\n");
+
+		while(discovery->running == true)
+		{
+			if(((status = discovery_unlock(shmData->semId, 2)) != CELIX_SUCCESS) && (discovery->running == true))
+			{
+				printf("DISCOVERY : discovery_pollSHMServices : cannot acquire semaphore\n");
+			}
+			else if(((status = discovery_lock(shmData->semId, 1)) != CELIX_SUCCESS) && (discovery->running == true))
+			{
+				printf("DISCOVERY : discovery_pollSHMServices : cannot acquire semaphore\n");
+			}
+			else
+			{
+				discovery_updateLocalSHMServices(discovery);
+
+				discovery_lock(shmData->semId, 2);
+				discovery_unlock(shmData->semId, 1);
+			}
+
+			sleep(1);
+		}
+	}
+
+	apr_thread_exit(thd, (status == CELIX_SUCCESS) ? APR_SUCCESS : -1);
+
+	return NULL;
+}
+

Added: incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery_activator.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery_activator.c?rev=1556172&view=auto
==============================================================================
--- incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery_activator.c (added)
+++ incubator/celix/trunk/remote_services/discovery_shm/private/src/discovery_activator.c Tue Jan  7 10:33:55 2014
@@ -0,0 +1,137 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * discovery_activator.c
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <apr_strings.h>
+#include <apr_uuid.h>
+
+#include "bundle_activator.h"
+#include "service_tracker.h"
+#include "service_registration.h"
+#include "constants.h"
+
+#include "discovery.h"
+#include "endpoint_listener.h"
+#include "remote_constants.h"
+
+struct activator {
+	apr_pool_t *pool;
+	bundle_context_pt context;
+
+	discovery_pt discovery;
+
+	service_tracker_pt endpointListenerTracker;
+	service_registration_pt endpointListenerService;
+};
+
+celix_status_t discoveryActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker);
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	apr_pool_t *parentPool = NULL;
+	apr_pool_t *pool = NULL;
+	struct activator *activator = NULL;
+
+	bundleContext_getMemoryPool(context, &parentPool);
+	apr_pool_create(&pool, parentPool);
+	activator = apr_palloc(pool, sizeof(*activator));
+	if (!activator) {
+		status = CELIX_ENOMEM;
+	} else {
+		activator->pool = pool;
+		activator->context = context;
+		activator->endpointListenerTracker = NULL;
+		activator->endpointListenerService = NULL;
+
+		discovery_create(pool, context, &activator->discovery);
+
+		discoveryActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
+
+		*userData = activator;
+	}
+
+	return status;
+}
+
+celix_status_t discoveryActivator_createEPLTracker(struct activator *activator,  service_tracker_pt *tracker) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(activator->pool, activator->discovery, discovery_endpointListenerAdding,
+			discovery_endpointListenerAdded, discovery_endpointListenerModified, discovery_endpointListenerRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(activator->pool, activator->context, "endpoint_listener", customizer, tracker);
+
+		serviceTracker_open(activator->endpointListenerTracker);
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	apr_pool_t *pool = NULL;
+	apr_pool_create(&pool, activator->pool);
+
+	endpoint_listener_pt endpointListener = apr_palloc(pool, sizeof(*endpointListener));
+	endpointListener->handle = activator->discovery;
+	endpointListener->endpointAdded = discovery_endpointAdded;
+	endpointListener->endpointRemoved = discovery_endpointRemoved;
+
+	properties_pt props = properties_create();
+	properties_set(props, "DISCOVERY", "true");
+	char *uuid = NULL;
+	bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+	char *scope = apr_pstrcat(activator->pool, "(&(", OSGI_FRAMEWORK_OBJECTCLASS, "=*)(", OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "=", uuid, "))", NULL);
+	printf("DISCOVERY SCOPE IS: %s\n", scope);
+	properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
+	status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService);
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	discovery_stop(activator->discovery);
+	serviceTracker_close(activator->endpointListenerTracker);
+	serviceRegistration_unregister(activator->endpointListenerService);
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+

Added: incubator/celix/trunk/remote_services/remote_service_admin_shm/CMakeLists.txt
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin_shm/CMakeLists.txt?rev=1556172&view=auto
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin_shm/CMakeLists.txt (added)
+++ incubator/celix/trunk/remote_services/remote_service_admin_shm/CMakeLists.txt Tue Jan  7 10:33:55 2014
@@ -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.
+celix_subproject(RSA_BUNDLES_REMOTE_SERVICE_ADMIN_SHM "Option to enable	building the Remote Service Admin Service SHM bundle" ON DEPS LAUNCHER topology_manager remote_service_admin)
+if (RSA_BUNDLES_REMOTE_SERVICE_ADMIN_SHM)
+	link_directories("/opt/local/lib")
+	include_directories("/opt/local/include")
+	include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+	include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+	include_directories("${PROJECT_SOURCE_DIR}/framework/private/include")
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/include")	
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_shm/public/include")
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_shm/private/include")
+	include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
+
+	SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_shm")
+	SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin SHM")
+
+	bundle(remote_service_admin_shm SOURCES 
+		private/src/remote_service_admin_impl
+		private/src/export_registration_impl
+		private/src/import_registration_impl
+		private/src/remote_service_admin_activator
+	)
+
+	install_bundle(remote_service_admin_shm
+		HEADERS
+			public/include/remote_endpoint_impl.h
+			public/include/remote_endpoint.h
+			public/include/remote_proxy.h
+			public/include/remote_service_admin.h
+	)
+
+	target_link_libraries(remote_service_admin_shm celix_framework ${APRUTIL_LIBRARY})
+endif (RSA_BUNDLES_REMOTE_SERVICE_ADMIN_SHM)

Added: incubator/celix/trunk/remote_services/remote_service_admin_shm/private/include/remote_service_admin_shm_impl.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin_shm/private/include/remote_service_admin_shm_impl.h?rev=1556172&view=auto
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin_shm/private/include/remote_service_admin_shm_impl.h (added)
+++ incubator/celix/trunk/remote_services/remote_service_admin_shm/private/include/remote_service_admin_shm_impl.h Tue Jan  7 10:33:55 2014
@@ -0,0 +1,76 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_shm_impl.h
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_SHM_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_SHM_IMPL_H_
+
+#include "remote_service_admin_impl.h"
+
+#define RSA_SHM_MEMSIZE 327680
+#define RSA_SHM_PATH_PROPERTYNAME "shmPath"
+#define RSA_SEM_PATH_PROPERTYNAME "semPath"
+#define RSA_SHM_FTOK_ID_PROPERTYNAME "shmFtokId"
+#define RSA_SEM_FTOK_ID_PROPERTYNAME "semFtokId"
+#define RSA_SHM_DEFAULTPATH "/dev/null"
+#define RSA_SEM_DEFAULTPATH "/dev/null"
+#define RSA_SHM_DEFAULT_FTOK_ID "52"
+#define RSA_SEM_DEFAULT_FTOK_ID "54"
+
+struct recv_shm_thread
+{
+	remote_service_admin_pt admin;
+	endpoint_description_pt endpointDescription;
+};
+
+struct ipc_segment
+{
+	int semId;
+	int shmId;
+	void *shmBaseAdress;
+};
+
+struct remote_service_admin {
+	apr_pool_t *pool;
+	bundle_context_pt context;
+
+	hash_map_pt exportedServices;
+	hash_map_pt importedServices;
+	hash_map_pt exportedIpcSegment;
+	hash_map_pt importedIpcSegment;
+
+	hash_map_pt pollThread;
+	hash_map_pt pollThreadRunning;
+
+	struct mg_context *ctx;
+};
+
+typedef struct recv_shm_thread *recv_shm_thread_pt;
+typedef struct ipc_segment *ipc_segment_pt;
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
+
+
+#endif /* REMOTE_SERVICE_ADMIN_SHM_IMPL_H_ */

Added: incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/export_registration_impl.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/export_registration_impl.c?rev=1556172&view=auto
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/export_registration_impl.c (added)
+++ incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/export_registration_impl.c Tue Jan  7 10:33:55 2014
@@ -0,0 +1,223 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * export_registration_impl.c
+ *
+ *  \date       Oct 6, 2011
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include <apr_strings.h>
+
+#include "celix_errno.h"
+
+#include "export_registration_impl.h"
+#include "remote_service_admin_impl.h"
+#include "service_tracker.h"
+#include "bundle_context.h"
+#include "bundle.h"
+#include "celix_log.h"
+
+celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service);
+celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *service);
+celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service);
+celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service);
+
+celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker);
+
+celix_status_t exportRegistration_create(apr_pool_t *pool, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	apr_pool_t *mypool = NULL;
+	apr_pool_create(&mypool, pool);
+
+	*registration = apr_palloc(mypool, sizeof(**registration));
+	if (!*registration) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*registration)->pool = mypool;
+		(*registration)->context = context;
+		(*registration)->closed = false;
+		(*registration)->endpointDescription = endpoint;
+		(*registration)->reference = reference;
+		(*registration)->rsa = rsa;
+		(*registration)->tracker = NULL;
+		(*registration)->endpoint = NULL;
+		(*registration)->endpointTracker = NULL;
+		(*registration)->exportReference = NULL;
+		(*registration)->bundle = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_startTracking(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->endpointTracker == NULL) {
+		status = exportRegistration_createEndpointTracker(registration, &registration->endpointTracker);
+		if (status == CELIX_SUCCESS) {
+			status = serviceTracker_open(registration->endpointTracker);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_stopTracking(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->endpointTracker != NULL) {
+		status = serviceTracker_close(registration->endpointTracker);
+		if (status != CELIX_SUCCESS) {
+		    fw_log(OSGI_FRAMEWORK_LOG_ERROR, "EXPORT_REGISTRATION: Could not close endpoint tracker");
+		}
+	}
+	if (registration->tracker != NULL) {
+		status = serviceTracker_close(registration->tracker);
+		if (status != CELIX_SUCCESS) {
+		    fw_log(OSGI_FRAMEWORK_LOG_ERROR, "EXPORT_REGISTRATION: Could not close service tracker");
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(registration->pool, registration, exportRegistration_endpointAdding,
+			exportRegistration_endpointAdded, exportRegistration_endpointModified, exportRegistration_endpointRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(registration->pool, registration->context, OSGI_RSA_REMOTE_ENDPOINT, customizer, tracker);
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	export_registration_pt registration = handle;
+
+	status = bundleContext_getService(registration->context, reference, service);
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	export_registration_pt registration = handle;
+
+	remote_endpoint_service_pt endpoint = service;
+	if (registration->endpoint == NULL) {
+		registration->endpoint = endpoint;
+		void *service = NULL;
+		status = bundleContext_getService(registration->context, registration->reference, &service);
+		if (status == CELIX_SUCCESS) {
+			endpoint->setService(endpoint->endpoint, service);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	export_registration_pt registration = handle;
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	export_registration_pt registration = handle;
+
+	remote_endpoint_service_pt endpoint = service;
+	if (registration->endpoint != NULL) {
+		registration->endpoint = NULL;
+		endpoint->setService(endpoint->endpoint, NULL);
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_open(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	char *bundleStore = NULL;
+	bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
+	if (bundleStore == NULL) {
+		bundleStore = DEFAULT_BUNDLE_STORE;
+	}
+	char *name = apr_pstrcat(registration->pool, bundleStore, "/", registration->endpointDescription->service, "_endpoint.zip", NULL);
+	status = bundleContext_installBundle(registration->context, name, &registration->bundle);
+	if (status == CELIX_SUCCESS) {
+		status = bundle_start(registration->bundle);
+		if (status == CELIX_SUCCESS) {
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_close(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	exportRegistration_stopTracking(registration);
+	bundle_stop(registration->bundle);
+	bundle_uninstall(registration->bundle);
+	remoteServiceAdmin_removeExportedService(registration);
+
+	return status;
+}
+
+celix_status_t exportRegistration_getException(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->exportReference == NULL) {
+		registration->exportReference = apr_palloc(registration->pool, sizeof(*registration->exportReference));
+		if (registration->exportReference == NULL) {
+			status = CELIX_ENOMEM;
+		} else {
+			registration->exportReference->endpoint = registration->endpointDescription;
+			registration->exportReference->reference = registration->reference;
+		}
+	}
+
+	*reference = registration->exportReference;
+
+	return status;
+}
+
+celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	registration->endpointDescription = endpointDescription;
+
+	return status;
+}

Added: incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/import_registration_impl.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/import_registration_impl.c?rev=1556172&view=auto
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/import_registration_impl.c (added)
+++ incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/import_registration_impl.c Tue Jan  7 10:33:55 2014
@@ -0,0 +1,256 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * import_registration_impl.c
+ *
+ *  \date       Oct 14, 2011
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+
+#include <apr_strings.h>
+
+#include <constants.h>
+
+#include "celix_errno.h"
+
+#include "import_registration_impl.h"
+#include "remote_service_admin_impl.h"
+#include "remote_proxy.h"
+#include "service_tracker.h"
+#include "bundle_context.h"
+#include "bundle.h"
+
+celix_status_t importRegistration_proxyAdding(void * handle, service_reference_pt reference, void **service);
+celix_status_t importRegistration_proxyAdded(void * handle, service_reference_pt reference, void *service);
+celix_status_t importRegistration_proxyModified(void * handle, service_reference_pt reference, void *service);
+celix_status_t importRegistration_proxyRemoved(void * handle, service_reference_pt reference, void *service);
+
+celix_status_t importRegistration_createProxyTracker(import_registration_pt registration, service_tracker_pt *tracker);
+
+celix_status_t importRegistration_create(apr_pool_t *pool, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, import_registration_pt *registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	apr_pool_t *mypool = NULL;
+	apr_pool_create(&mypool, pool);
+
+	*registration = apr_palloc(mypool, sizeof(**registration));
+	if (!*registration) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*registration)->pool = mypool;
+		(*registration)->context = context;
+		(*registration)->closed = false;
+		(*registration)->endpointDescription = endpoint;
+		(*registration)->rsa = rsa;
+		(*registration)->proxy = NULL;
+		(*registration)->reference = NULL;
+		(*registration)->proxyTracker = NULL;
+		(*registration)->bundle = NULL;
+		(*registration)->importReference = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_startTracking(import_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->proxyTracker == NULL) {
+		importRegistration_createProxyTracker(registration, &registration->proxyTracker);
+		serviceTracker_open(registration->proxyTracker);
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_stopTracking(import_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->proxyTracker != NULL) {
+		serviceTracker_close(registration->proxyTracker);
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_createProxyTracker(import_registration_pt registration, service_tracker_pt *tracker) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(registration->pool, registration, importRegistration_proxyAdding,
+			importRegistration_proxyAdded, importRegistration_proxyModified, importRegistration_proxyRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		char *filter = apr_pstrcat(registration->pool, "(&(", OSGI_FRAMEWORK_OBJECTCLASS, "=", OSGI_RSA_REMOTE_PROXY,
+				")(proxy.interface=", registration->endpointDescription->service, "))", NULL);
+		status = serviceTracker_createWithFilter(registration->pool, registration->context, filter, customizer, tracker);
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyAdding(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	import_registration_pt registration = handle;
+
+	bundleContext_getService(registration->context, reference, service);
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyAdded(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	import_registration_pt registration = handle;
+	remote_proxy_service_pt proxy = (remote_proxy_service_pt) service;
+
+	if (registration->proxy == NULL) {
+		registration->reference = reference;
+		registration->proxy = proxy;
+		if (registration->endpointDescription != NULL) {
+			proxy->setEndpointDescription(proxy->proxy, registration->endpointDescription);
+			proxy->setHandler(proxy->proxy, registration->rsa);
+			proxy->setCallback(proxy->proxy, (sendToHandle) &remoteServiceAdmin_send);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyModified(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	import_registration_pt registration = handle;
+
+	//remote_proxy_service_pt endpoint = service;
+	//if (registration->endpoint != NULL) {
+	//	registration->endpoint = endpoint;
+	//	endpoint->setServiceReference(endpoint->endpoint, registration->reference);
+	//}
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyRemoved(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	import_registration_pt registration = handle;
+
+	remote_proxy_service_pt proxy = service;
+	if (registration->proxy != NULL) {
+		registration->reference = NULL;
+		registration->proxy = NULL;
+		proxy->setEndpointDescription(proxy->proxy, NULL);
+		proxy->setHandler(proxy->proxy, NULL);
+		proxy->setCallback(proxy->proxy, NULL);
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_open(import_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	char *bundleStore = NULL;
+	bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
+
+	if (bundleStore == NULL) {
+		bundleStore = DEFAULT_BUNDLE_STORE;
+	}
+
+	char *name = apr_pstrcat(registration->pool, bundleStore, "/", registration->endpointDescription->service, "_proxy.zip", NULL);
+	status = bundleContext_installBundle(registration->context, name, &registration->bundle);
+
+	if (status == CELIX_SUCCESS) {
+		status = bundle_start(registration->bundle);
+		if (status == CELIX_SUCCESS) {
+		}
+	}
+	return status;
+}
+
+celix_status_t importRegistration_close(import_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	importRegistration_stopTracking(registration);
+
+	if (registration->bundle != NULL) {
+		bundle_stop(registration->bundle);
+		bundle_uninstall(registration->bundle);
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_getException(import_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->importReference == NULL) {
+		registration->importReference = apr_palloc(registration->pool, sizeof(*registration->importReference));
+		if (registration->importReference == NULL) {
+			status = CELIX_ENOMEM;
+		} else {
+			registration->importReference->endpoint = registration->endpointDescription;
+			registration->importReference->reference = registration->reference;
+		}
+	}
+
+	*reference = registration->importReference;
+
+	return status;
+}
+
+celix_status_t importRegistration_setEndpointDescription(import_registration_pt registration, endpoint_description_pt endpointDescription) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	registration->endpointDescription = endpointDescription;
+	if (registration->proxy != NULL) {
+		registration->proxy->setEndpointDescription(registration->proxy->proxy, endpointDescription);
+	}
+
+	return status;
+}
+
+
+celix_status_t importRegistration_setHandler(import_registration_pt registration, void * handler) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->proxy != NULL) {
+		registration->proxy->setHandler(registration->proxy->proxy, handler);
+	}
+
+	return status;
+}
+
+
+celix_status_t importRegistration_setCallback(import_registration_pt registration, sendToHandle callback) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->proxy != NULL) {
+		registration->proxy->setCallback(registration->proxy->proxy, callback);
+	}
+
+	return status;
+}
+

Added: incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_activator.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_activator.c?rev=1556172&view=auto
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_activator.c (added)
+++ incubator/celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_activator.c Tue Jan  7 10:33:55 2014
@@ -0,0 +1,124 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_activator.c
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+
+#include "remote_service_admin_shm_impl.h"
+#include "export_registration_impl.h"
+#include "import_registration_impl.h"
+
+struct activator {
+	apr_pool_t *pool;
+	remote_service_admin_pt admin;
+	service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	apr_pool_t *parentPool = NULL;
+	apr_pool_t *pool = NULL;
+	struct activator *activator;
+
+	status = bundleContext_getMemoryPool(context, &parentPool);
+	if (status == CELIX_SUCCESS) {
+		if (apr_pool_create(&pool, parentPool) != APR_SUCCESS) {
+			status = CELIX_BUNDLE_EXCEPTION;
+		} else {
+			activator = apr_palloc(pool, sizeof(*activator));
+			if (!activator) {
+				status = CELIX_ENOMEM;
+			} else {
+				activator->pool = pool;
+				activator->admin = NULL;
+				activator->registration = NULL;
+
+				*userData = activator;
+			}
+		}
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	remote_service_admin_service_pt remoteServiceAdmin = NULL;
+
+	status = remoteServiceAdmin_create(activator->pool, context, &activator->admin);
+	if (status == CELIX_SUCCESS) {
+		remoteServiceAdmin = apr_palloc(activator->pool, sizeof(*remoteServiceAdmin));
+		if (!remoteServiceAdmin) {
+			status = CELIX_ENOMEM;
+		} else {
+			remoteServiceAdmin->admin = activator->admin;
+			remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
+			remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
+			remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
+			remoteServiceAdmin->importService = remoteServiceAdmin_importService;
+
+			remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
+			remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
+
+			remoteServiceAdmin->exportRegistration_close = exportRegistration_close;
+			remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
+			remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
+
+			remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
+			remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
+
+			remoteServiceAdmin->importRegistration_close = importRegistration_close;
+			remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
+			remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
+
+			status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	remoteServiceAdmin_stop(activator->admin);
+	serviceRegistration_unregister(activator->registration);
+	activator->registration = NULL;
+
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	return status;
+}
+
+