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 2020/02/11 20:30:28 UTC

[celix] branch feature/gh-142-rsa-issues updated: #142: Refactors remote calculator client to use celix_ api.

This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/gh-142-rsa-issues
in repository https://gitbox.apache.org/repos/asf/celix.git


The following commit(s) were added to refs/heads/feature/gh-142-rsa-issues by this push:
     new 28cce03  #142: Refactors remote calculator client to use celix_ api.
28cce03 is described below

commit 28cce03d5c2515d60d076a1cae6d8735ed387fd5
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Tue Feb 11 21:30:13 2020 +0100

    #142: Refactors remote calculator client to use celix_ api.
---
 bundles/remote_services/examples/CMakeLists.txt    |   5 +-
 .../examples/calculator_shell/src/add_command.c    |  92 ++++++++---------
 .../examples/calculator_shell/src/add_command.h    |  10 +-
 .../src/calculator_shell_activator.c               | 110 ++++++---------------
 ...org.apache.celix.calc.api.Calculator.descriptor |  11 ---
 .../examples/calculator_shell/src/sqrt_command.c   |  87 ++++++++--------
 .../examples/calculator_shell/src/sqrt_command.h   |  10 +-
 .../examples/calculator_shell/src/sub_command.c    |  94 +++++++++---------
 .../examples/calculator_shell/src/sub_command.h    |  10 +-
 bundles/shell/shell/src/help_command.c             |   5 +
 10 files changed, 187 insertions(+), 247 deletions(-)

diff --git a/bundles/remote_services/examples/CMakeLists.txt b/bundles/remote_services/examples/CMakeLists.txt
index c9feea5..17dcabf 100644
--- a/bundles/remote_services/examples/CMakeLists.txt
+++ b/bundles/remote_services/examples/CMakeLists.txt
@@ -54,11 +54,12 @@ if (RSA_EXAMPLES)
             BUNDLES
                 Celix::rsa_discovery_etcd
                 Celix::rsa_topology_manager
-                Celix::rsa_dfi calculator
+                Celix::rsa_dfi
                 Celix::shell
                 Celix::shell_tui
                 Celix::log_service
                 Celix::log_writer_stdout
+                calculator
             PROPERTIES
                 RSA_PORT=18888
         )
@@ -72,8 +73,8 @@ if (RSA_EXAMPLES)
                 Celix::shell_tui
                 Celix::log_service
                 Celix::log_writer_stdout
-                calculator_shell
                 Celix::rsa_discovery_etcd
+                calculator_shell
             PROPERTIES
                 RSA_PORT=28888
         )
diff --git a/bundles/remote_services/examples/calculator_shell/src/add_command.c b/bundles/remote_services/examples/calculator_shell/src/add_command.c
index bc4f1fd..094a0e3 100644
--- a/bundles/remote_services/examples/calculator_shell/src/add_command.c
+++ b/bundles/remote_services/examples/calculator_shell/src/add_command.c
@@ -16,70 +16,74 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * add_command.c
- *
- *  \date       Oct 13, 2011
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
 
-#include "array_list.h"
-#include "bundle_context.h"
+#include "celix_api.h"
 #include "add_command.h"
 #include "calculator_service.h"
+#include "celix_utils.h"
 
 
 static celix_status_t addCommand_isNumeric(char *number, bool *ret);
 
-void addCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err) {
-    celix_status_t status = CELIX_SUCCESS;
-    service_reference_pt calculatorService = NULL;
+struct calc_callback_data {
+    double a;
+    double b;
+    double result;
+    int rc;
+};
 
-    status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
-    if (calculatorService == NULL) {
-        fprintf(err, "ADD: Cannot get reference for %s.\n", CALCULATOR_SERVICE);
-    }
-    if (status == CELIX_SUCCESS) {
-        char *token = line;
-        strtok_r(line, " ", &token);
-        char *aStr = strtok_r(NULL, " ", &token);
-        char *bStr = strtok_r(NULL, " ", &token);
-        bool aNumeric, bNumeric;
-        if (aStr != NULL && bStr != NULL) {
-            addCommand_isNumeric(aStr, &aNumeric);
-            addCommand_isNumeric(bStr, &bNumeric);
-            if (aNumeric && bNumeric) {
-                calculator_service_t *calculator = NULL;
-                status = bundleContext_getService(context, calculatorService, (void *) &calculator);
-                if (status == CELIX_SUCCESS && calculator != NULL) {
-                    double a = atof(aStr);
-                    double b = atof(bStr);
-                    double result = 0;
-                    status = calculator->add(calculator->handle, a, b, &result);
-                    if (status == CELIX_SUCCESS) {
-                        fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", a, b, result);
-                    } else {
-                        fprintf(err, "ADD: Unexpected exception in Calc service\n");
-                    }
-                } else {
-                    fprintf(err, "No calc service available\n");
-                }
+static void calcCallback(void *handle, void *svc) {
+    struct calc_callback_data *data = handle;
+    calculator_service_t *calc = svc;
+    data->rc = calc->add(calc->handle, data->a, data->b, &data->result);
+}
+
+bool addCommand_execute(void *handle, const char *const_line, FILE *out, FILE *err) {
+    bool ok = true;
+    celix_bundle_context_t *context = handle;
+
+    char *line = celix_utils_strdup(const_line);
+
+    char *token = line;
+    strtok_r(line, " ", &token);
+    char *aStr = strtok_r(NULL, " ", &token);
+    char *bStr = strtok_r(NULL, " ", &token);
+    bool aNumeric, bNumeric;
+    if (aStr != NULL && bStr != NULL) {
+        addCommand_isNumeric(aStr, &aNumeric);
+        addCommand_isNumeric(bStr, &bNumeric);
+        if (aNumeric && bNumeric) {
+            struct calc_callback_data data;
+
+            data.a = atof(aStr);
+            data.b = atof(bStr);
+            data.result = 0;
+            data.rc = 0;
+            bool called = celix_bundleContext_useService(context, CALCULATOR_SERVICE, &data, calcCallback);
+            if (called && data.rc == 0) {
+                fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", data.a, data.b, data.result);
+            } else if (!called) {
+                fprintf(err, "ADD: calculator service not available\n");
+                ok = false;
             } else {
-                fprintf(err, "ADD: Requires 2 numerical parameter\n");
+                fprintf(err, "ADD: Unexpected exception in Calc service\n");
+                ok = false;
             }
         } else {
             fprintf(err, "ADD: Requires 2 numerical parameter\n");
+            ok = false;
         }
     } else {
-        fprintf(err, "No calc service available\n");
+        fprintf(err, "ADD: Requires 2 numerical parameter\n");
+        ok = false;
     }
 
-    //return status;
+    free(line);
+    return ok;
 }
 
 static celix_status_t addCommand_isNumeric(char *number, bool *ret) {
diff --git a/bundles/remote_services/examples/calculator_shell/src/add_command.h b/bundles/remote_services/examples/calculator_shell/src/add_command.h
index 505fbab..40a4de3 100644
--- a/bundles/remote_services/examples/calculator_shell/src/add_command.h
+++ b/bundles/remote_services/examples/calculator_shell/src/add_command.h
@@ -16,17 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * add_command.h
- *
- *  \date       Oct 13, 2011
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
 
 #ifndef ADD_COMMAND_H_
 #define ADD_COMMAND_H_
 
-void addCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err);
+bool addCommand_execute(void *handle, const char *line, FILE *out, FILE *err);
 
 #endif /* ADD_COMMAND_H_ */
diff --git a/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c b/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
index 05f5736..6cf1d5a 100644
--- a/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
+++ b/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
@@ -19,101 +19,51 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <celix_shell_command.h>
 
-#include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
+
+#include "celix_shell_command.h"
+#include "celix_api.h"
 
 #include "add_command.h"
 #include "sub_command.h"
 #include "sqrt_command.h"
 
-struct activator {
-    service_registration_t *addCommand;
-    celix_shell_command_t *addCmd;
-    celix_shell_command_t *addCmdSrv;
-
-    service_registration_t *subCommand;
-    celix_shell_command_t *subCmd;
-    celix_shell_command_t *subCmdSrv;
-
-    service_registration_t *sqrtCommand;
-    celix_shell_command_t *sqrtCmd;
-    celix_shell_command_t *sqrtCmdSrv;
-};
-
-celix_status_t bundleActivator_create(celix_bundle_context_t *context, void **userData) {
-    celix_status_t status = CELIX_SUCCESS;
-    if (status == CELIX_SUCCESS) {
-        *userData = calloc(1, sizeof(struct activator));
-        if (!*userData) {
-            status = CELIX_ENOMEM;
-        } else {
-            ((struct activator *) (*userData))->addCommand = NULL;
-            ((struct activator *) (*userData))->subCommand = NULL;
-            ((struct activator *) (*userData))->sqrtCommand = NULL;
-
-            ((struct activator *) (*userData))->addCmd = NULL;
-            ((struct activator *) (*userData))->subCmd = NULL;
-            ((struct activator *) (*userData))->sqrtCmd = NULL;
-
-            ((struct activator *) (*userData))->addCmdSrv = NULL;
-            ((struct activator *) (*userData))->subCmdSrv = NULL;
-            ((struct activator *) (*userData))->sqrtCmdSrv = NULL;
-        }
-    }
-
-    return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, celix_bundle_context_t *context) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    struct activator * activator = (struct activator *) userData;
-
-    activator->addCmdSrv = calloc(1, sizeof(*activator->addCmdSrv));
-    activator->addCmdSrv->handle = context;
-    activator->addCmdSrv->executeCommand = (void *)addCommand_execute;
+typedef struct calc_shell_activator {
+    long addCmdSvcId;
+    celix_shell_command_t addCmd;
+    long subCmdSvcId;
+    celix_shell_command_t subCmd;
+    long sqrtCmdSvcId;
+    celix_shell_command_t sqrtCmd;
+} calc_shell_activator_t;
+
+static celix_status_t calcShell_start(calc_shell_activator_t *activator, celix_bundle_context_t *ctx) {
+    activator->addCmd.handle = ctx;
+    activator->addCmd.executeCommand = addCommand_execute;
     celix_properties_t *props = celix_properties_create();
     celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "add");
-    bundleContext_registerService(context, (char *)CELIX_SHELL_COMMAND_SERVICE_NAME, activator->addCmdSrv, props, &activator->addCommand);
+    activator->addCmdSvcId = celix_bundleContext_registerService(ctx, &activator->addCmd, CELIX_SHELL_COMMAND_SERVICE_NAME, props);
 
-
-    activator->sqrtCmdSrv = calloc(1, sizeof(*activator->sqrtCmdSrv));
-    activator->sqrtCmdSrv->handle = context;
-    activator->sqrtCmdSrv->executeCommand = (void *)sqrtCommand_execute;
-    props = celix_properties_create();
-    celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "sqrt");
-    bundleContext_registerService(context, (char *)CELIX_SHELL_COMMAND_SERVICE_NAME, activator->sqrtCmdSrv, props, &activator->sqrtCommand);
-
-    activator->subCmdSrv = calloc(1, sizeof(*activator->subCmdSrv));
-    activator->subCmdSrv->handle = context;
-    activator->subCmdSrv->executeCommand = (void *)subCommand_execute;
+    activator->subCmd.handle = ctx;
+    activator->subCmd.executeCommand = subCommand_execute;
     props = celix_properties_create();
     celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "sub");
-    bundleContext_registerService(context, (char *)CELIX_SHELL_COMMAND_SERVICE_NAME, activator->subCmdSrv, props, &activator->subCommand);
-
-    return status;
-}
+    activator->subCmdSvcId = celix_bundleContext_registerService(ctx, &activator->subCmd, CELIX_SHELL_COMMAND_SERVICE_NAME, props);
 
+    activator->sqrtCmd.handle = ctx;
+    activator->sqrtCmd.executeCommand = sqrtCommand_execute;
+    props = celix_properties_create();
+    celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "sqrt");
+    activator->sqrtCmdSvcId = celix_bundleContext_registerService(ctx, &activator->sqrtCmd, CELIX_SHELL_COMMAND_SERVICE_NAME, props);
 
-celix_status_t bundleActivator_stop(void * userData, celix_bundle_context_t *context) {
-    celix_status_t status = CELIX_SUCCESS;
-    struct activator * activator = (struct activator *) userData;
-    serviceRegistration_unregister(activator->addCommand);
-    serviceRegistration_unregister(activator->subCommand);
-    serviceRegistration_unregister(activator->sqrtCommand);
-
-    free(activator->addCmdSrv);
-    free(activator->subCmdSrv);
-    free(activator->sqrtCmdSrv);
-
-    return status;
+    return CELIX_SUCCESS;
 }
 
-celix_status_t bundleActivator_destroy(void * userData, celix_bundle_context_t *context) {
-    free(userData);
+static celix_status_t calcShell_stop(calc_shell_activator_t *activator, celix_bundle_context_t *ctx) {
+    celix_bundleContext_unregisterService(ctx, activator->addCmdSvcId);
+    celix_bundleContext_unregisterService(ctx, activator->subCmdSvcId);
+    celix_bundleContext_unregisterService(ctx, activator->sqrtCmdSvcId);
     return CELIX_SUCCESS;
 }
 
+CELIX_GEN_BUNDLE_ACTIVATOR(calc_shell_activator_t, calcShell_start, calcShell_stop);
diff --git a/bundles/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator.descriptor b/bundles/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator.descriptor
deleted file mode 100644
index 35b4df7..0000000
--- a/bundles/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator.descriptor
+++ /dev/null
@@ -1,11 +0,0 @@
-:header
-type=interface
-name=calculator
-version=1.2.3
-:annotations
-classname=org.example.Calculator
-:types
-:methods
-add(DD)D=add(#am=handle;PDD#am=pre;*D)N
-sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
-sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N
diff --git a/bundles/remote_services/examples/calculator_shell/src/sqrt_command.c b/bundles/remote_services/examples/calculator_shell/src/sqrt_command.c
index c014092..175040a 100644
--- a/bundles/remote_services/examples/calculator_shell/src/sqrt_command.c
+++ b/bundles/remote_services/examples/calculator_shell/src/sqrt_command.c
@@ -16,66 +16,71 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * sqrt_command.c
- *
- *  \date       Oct 13, 2011
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
 
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
 
-#include "array_list.h"
-#include "bundle_context.h"
+#include "celix_api.h"
+#include "celix_utils.h"
 #include "sqrt_command.h"
 #include "calculator_service.h"
 
 static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret);
 
-void sqrtCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err) {
-    celix_status_t status = CELIX_SUCCESS;
-    service_reference_pt calculatorService = NULL;
+struct calc_callback_data {
+    double a;
+    double result;
+    int rc;
+};
 
-    status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
-    if (calculatorService == NULL) {
-        fprintf(err, "SQRT: Cannot get reference for %s.\n", CALCULATOR_SERVICE);
-    }
-    if (status == CELIX_SUCCESS) {
-        char *token = line;
-        strtok_r(line, " ", &token);
-        char *aStr = strtok_r(NULL, " ", &token);
-        if(aStr != NULL){
-            bool numeric;
-            sqrtCommand_isNumeric(aStr, &numeric);
-            if (numeric) {
-                calculator_service_t *calculator = NULL;
-                status = bundleContext_getService(context, calculatorService, (void *) &calculator);
-                if (status == CELIX_SUCCESS && calculator != NULL) {
-                    double a = atof(aStr);
-                    double result = 0;
-                    status = calculator->sqrt(calculator->handle, a, &result);
-                    if (status == CELIX_SUCCESS) {
-                        fprintf(out, "CALCULATOR_SHELL: Sqrt: %f = %f\n", a, result);
-                    } else {
-                        fprintf(err, "SQRT: Unexpected exception in Calc service\n");
-                    }
-                } else {
-                    fprintf(err, "No calc service available\n");
-                }
+static void calcCallback(void *handle, void *svc) {
+    struct calc_callback_data *data = handle;
+    calculator_service_t *calc = svc;
+    data->rc = calc->sqrt(calc->handle, data->a, &data->result);
+}
+
+bool sqrtCommand_execute(void *handle, const char *const_line, FILE *out, FILE *err) {
+    celix_bundle_context_t *context = handle;
+    bool ok = true;
+    char *line = celix_utils_strdup(const_line);
+
+
+    char *token = line;
+    strtok_r(line, " ", &token);
+    char *aStr = strtok_r(NULL, " ", &token);
+    if(aStr != NULL) {
+        bool numeric;
+        sqrtCommand_isNumeric(aStr, &numeric);
+        if (numeric) {
+            struct calc_callback_data data;
+
+            data.a = atof(aStr);
+            data.result = 0;
+            data.rc = 0;
+            bool called = celix_bundleContext_useService(context, CALCULATOR_SERVICE, &data, calcCallback);
+            if (called && data.rc == 0) {
+                fprintf(out, "CALCULATOR_SHELL: Sqrt: %f = %f\n", data.a, data.result);
+            } else if (!called) {
+                fprintf(err, "ADD: calculator service not available\n");
+                ok = false;
             } else {
-                fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+                fprintf(err, "ADD: Unexpected exception in Calc service\n");
+                ok = false;
             }
         } else {
             fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+            ok = false;
         }
     } else {
-        fprintf(err, "No calc service available\n");
+        fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+        ok = false;
     }
 
-    //return status;
+    free(line);
+
+    return ok;
 }
 
 static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret) {
diff --git a/bundles/remote_services/examples/calculator_shell/src/sqrt_command.h b/bundles/remote_services/examples/calculator_shell/src/sqrt_command.h
index 65b5e7d..317363d 100644
--- a/bundles/remote_services/examples/calculator_shell/src/sqrt_command.h
+++ b/bundles/remote_services/examples/calculator_shell/src/sqrt_command.h
@@ -16,17 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * sqrt_command.h
- *
- *  \date       Oct 13, 2011
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
 
 #ifndef SQRT_COMMAND_H_
 #define SQRT_COMMAND_H_
 
-void sqrtCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err);
+bool sqrtCommand_execute(void *handle, const char *line, FILE *out, FILE *err);
 
 #endif /* SQRT_COMMAND_H_ */
diff --git a/bundles/remote_services/examples/calculator_shell/src/sub_command.c b/bundles/remote_services/examples/calculator_shell/src/sub_command.c
index b275b6c..9a1f89d 100644
--- a/bundles/remote_services/examples/calculator_shell/src/sub_command.c
+++ b/bundles/remote_services/examples/calculator_shell/src/sub_command.c
@@ -16,69 +16,73 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * sub_command.c
- *
- *  \date       Oct 13, 2011
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
 
-#include "array_list.h"
-#include "bundle_context.h"
+#include "celix_utils.h"
+#include "celix_api.h"
 #include "sub_command.h"
 #include "calculator_service.h"
 
 static celix_status_t subCommand_isNumeric(char *number, bool *ret);
 
-void subCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err) {
-    celix_status_t status = CELIX_SUCCESS;
-    service_reference_pt calculatorService = NULL;
+struct calc_callback_data {
+    double a;
+    double b;
+    double result;
+    int rc;
+};
 
-    status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
-    if (calculatorService == NULL) {
-        fprintf(err, "SUB: Cannot get reference for %s\n", CALCULATOR_SERVICE);
-    }
-    if (status == CELIX_SUCCESS) {
-        char *token = line;
-        strtok_r(line, " ", &token);
-        char *aStr = strtok_r(NULL, " ", &token);
-        char *bStr = strtok_r(NULL, " ", &token);
-        if(aStr != NULL && bStr != NULL ){
-            bool aNumeric, bNumeric;
-            subCommand_isNumeric(aStr, &aNumeric);
-            subCommand_isNumeric(bStr, &bNumeric);
-            if (aNumeric && bNumeric) {
-                calculator_service_t *calculator = NULL;
-                status = bundleContext_getService(context, calculatorService, (void *) &calculator);
-                if (status == CELIX_SUCCESS && calculator != NULL) {
-                    double a = atof(aStr);
-                    double b = atof(bStr);
-                    double result = 0;
-                    status = calculator->sub(calculator->handle, a, b, &result);
-                    if (status == CELIX_SUCCESS) {
-                        fprintf(out, "CALCULATOR_SHELL: Sub: %f - %f = %f\n", a, b, result);
-                    } else {
-                        fprintf(err, "SUB: Unexpected exception in Calc service\n");
-                    }
-                } else {
-                    fprintf(err, "No calc service available\n");
-                }
+static void calcCallback(void *handle, void *svc) {
+    struct calc_callback_data *data = handle;
+    calculator_service_t *calc = svc;
+    data->rc = calc->sub(calc->handle, data->a, data->b, &data->result);
+}
+
+bool subCommand_execute(void *handle, const char *const_line, FILE *out, FILE *err) {
+    bool ok = true;
+    celix_bundle_context_t *context = handle;
+
+    char *line = celix_utils_strdup(const_line);
+
+    char *token = line;
+    strtok_r(line, " ", &token);
+    char *aStr = strtok_r(NULL, " ", &token);
+    char *bStr = strtok_r(NULL, " ", &token);
+    bool aNumeric, bNumeric;
+    if (aStr != NULL && bStr != NULL) {
+        subCommand_isNumeric(aStr, &aNumeric);
+        subCommand_isNumeric(bStr, &bNumeric);
+        if (aNumeric && bNumeric) {
+            struct calc_callback_data data;
+
+            data.a = atof(aStr);
+            data.b = atof(bStr);
+            data.result = 0;
+            data.rc = 0;
+            bool called = celix_bundleContext_useService(context, CALCULATOR_SERVICE, &data, calcCallback);
+            if (called && data.rc == 0) {
+                fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", data.a, data.b, data.result);
+            } else if (!called) {
+                fprintf(err, "Sub: calculator service not available\n");
+                ok = false;
             } else {
-                fprintf(err, "SUB: Requires 2 numerical parameter\n");
+                fprintf(err, "Sub: Unexpected exception in Calc service\n");
+                ok = false;
             }
         } else {
-            fprintf(err, "SUB: Requires 2 numerical parameter\n");
+            fprintf(err, "Sub: Requires 2 numerical parameter\n");
+            ok = false;
         }
     } else {
-        fprintf(err, "No calc service available\n");
+        fprintf(err, "Sub: Requires 2 numerical parameter\n");
+        ok = false;
     }
 
-    //return status;
+    free(line);
+    return ok;
 }
 
 static celix_status_t subCommand_isNumeric(char *number, bool *ret) {
diff --git a/bundles/remote_services/examples/calculator_shell/src/sub_command.h b/bundles/remote_services/examples/calculator_shell/src/sub_command.h
index 33a94c3..7673089 100644
--- a/bundles/remote_services/examples/calculator_shell/src/sub_command.h
+++ b/bundles/remote_services/examples/calculator_shell/src/sub_command.h
@@ -16,17 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * sub_command.h
- *
- *  \date       Oct 13, 2011
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
 
 #ifndef SUB_COMMAND_H_
 #define SUB_COMMAND_H_
 
-void subCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err);
+bool subCommand_execute(void *handle, const char *line, FILE *out, FILE *err);
 
 #endif /* SUB_COMMAND_H_ */
diff --git a/bundles/shell/shell/src/help_command.c b/bundles/shell/shell/src/help_command.c
index accf620..fa124bb 100644
--- a/bundles/shell/shell/src/help_command.c
+++ b/bundles/shell/shell/src/help_command.c
@@ -92,6 +92,11 @@ static void printHelp(void *handle, void *svc) {
             free(name);
         }
         celix_arrayList_destroy(commands);
+
+        if (!cmdFound) {
+            fprintf(out, "Command '%s' not found. Type 'help' to get an overview of the available commands\n", sub);
+        }
+
         p->callSucceeded = cmdFound;
     }
 }