Return-Path: X-Original-To: apmail-celix-commits-archive@www.apache.org Delivered-To: apmail-celix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id BAD4418994 for ; Thu, 3 Sep 2015 14:20:22 +0000 (UTC) Received: (qmail 30947 invoked by uid 500); 3 Sep 2015 14:20:22 -0000 Delivered-To: apmail-celix-commits-archive@celix.apache.org Received: (qmail 30921 invoked by uid 500); 3 Sep 2015 14:20:22 -0000 Mailing-List: contact commits-help@celix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@celix.apache.org Delivered-To: mailing list commits@celix.apache.org Received: (qmail 30903 invoked by uid 99); 3 Sep 2015 14:20:22 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 03 Sep 2015 14:20:22 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 58928DFFD5; Thu, 3 Sep 2015 14:20:22 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: pnoltes@apache.org To: commits@celix.apache.org Date: Thu, 03 Sep 2015 14:20:22 -0000 Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: [1/2] celix git commit: CELIX-237: Refactored meta chars in dyn_function to a more generic meta property setup in dyn_type. Split of rpc / serialization json stuff Repository: celix Updated Branches: refs/heads/feature/CELIX-237_rsa-ffi 89968d937 -> c0d4f75af CELIX-237: Refactored meta chars in dyn_function to a more generic meta property setup in dyn_type. Split of rpc / serialization json stuff Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/837926e6 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/837926e6 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/837926e6 Branch: refs/heads/feature/CELIX-237_rsa-ffi Commit: 837926e6bdfa0ba97beb00c0db52146a68d74911 Parents: 89968d9 Author: Pepijn Noltes Authored: Wed Sep 2 17:43:28 2015 +0200 Committer: Pepijn Noltes Committed: Wed Sep 2 17:43:28 2015 +0200 ---------------------------------------------------------------------- ...apache.celix.calc.api.Calculator2.descriptor | 6 +- .../dynamic_function_interface/CMakeLists.txt | 1 + .../dynamic_function_interface/dyn_function.c | 68 ------ .../dynamic_function_interface/dyn_function.h | 18 +- .../dynamic_function_interface/dyn_type.c | 85 +++++++ .../dynamic_function_interface/dyn_type.h | 11 +- .../dynamic_function_interface/json_rpc.c | 235 +++++++++++++++++++ .../dynamic_function_interface/json_rpc.h | 22 ++ .../json_serializer.c | 213 ----------------- .../json_serializer.h | 4 - .../CMakeLists.txt | 1 + .../dyn_function_tests.cpp | 38 --- .../dyn_type_tests.cpp | 24 +- .../json_rpc_tests.cpp | 61 +++++ .../rsa/private/src/export_registration_dfi.c | 9 +- .../rsa/private/src/import_registration_dfi.c | 5 +- 16 files changed, 451 insertions(+), 350 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor ---------------------------------------------------------------------- diff --git a/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor index 52e3322..c8ba53d 100644 --- a/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor +++ b/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor @@ -6,6 +6,6 @@ version=1.0.0 classname=org.example.Calculator :types :methods -add(DD)D=add(#PDD^*D)N -sub(DD)D=sub(#PDD^*D)N -sqrt(D)D=sqrt(#PD^*D)N +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 http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt index 142ae32..aefd243 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(dfi STATIC dyn_function.c dyn_interface.c json_serializer.c + json_rpc.c ${MEMSTREAM_SOURCES} ) target_link_libraries(dfi ${FFI_LIBRARIES} ${JANSSON_LIBRARY}) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c index 06f6aaa..abd27d0 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c @@ -43,10 +43,6 @@ static int dynFunction_initCif(dyn_function_type *dynFunc); static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descriptor); static void dynFunction_ffiBind(ffi_cif *cif, void *ret, void *args[], void *userData); -static int dynFunction_checkArgument(dyn_function_argument_type *argument); - -static void dynFunction_parseArgMeta(FILE *descriptor, int *meta); - int dynFunction_parse(FILE *descriptor, struct types_head *refTypes, dyn_function_type **out) { int status = OK; dyn_function_type *dynFunc = NULL; @@ -116,13 +112,11 @@ static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descrip int nextChar = fgetc(descriptor); int index = 0; dyn_type *type = NULL; - int argMetaInfo = DYN_FUNCTION_ARG_META_INPUT_TYPE; char argName[32]; while (nextChar != ')' && status == 0) { ungetc(nextChar, descriptor); type = NULL; - dynFunction_parseArgMeta(descriptor, &argMetaInfo); dyn_function_argument_type *arg = NULL; status = dynType_parse(descriptor, NULL, dynFunc->refTypes, &type); @@ -131,8 +125,6 @@ static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descrip if (arg != NULL) { arg->index = index; arg->type = type; - arg->argumentType = argMetaInfo; - snprintf(argName, 32, "arg%04i", index); arg->name = strdup(argName); @@ -144,10 +136,6 @@ static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descrip } if (status == 0) { - status = dynFunction_checkArgument(arg); - } - - if (status == 0) { TAILQ_INSERT_TAIL(&dynFunc->arguments, arg, entries); } else { if (arg != NULL) { @@ -170,47 +158,6 @@ static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descrip return status; } -static void dynFunction_parseArgMeta(FILE *descriptor, int *meta) { - int c = fgetc(descriptor); - - switch (c) { - case '~' : - *meta = DYN_FUNCTION_ARG_META_OUTPUT_TYPE; - break; - case '^' : - *meta = DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE; - break; - case '#' : - *meta = DYN_FUNCTION_ARG_META_HANDLE_TYPE; - break; - default : - *meta = DYN_FUNCTION_ARG_META_INPUT_TYPE; - ungetc(c, descriptor); - break; - } -} - -static int dynFunction_checkArgument(dyn_function_argument_type *argument) { - int status = 0; - if (argument->argumentType == DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE) { - //expect atleast one * - if (dynType_type(argument->type) != DYN_TYPE_TYPED_POINTER) { - status = ERROR; - } - } else if (argument->argumentType == DYN_FUNCTION_ARG_META_OUTPUT_TYPE) { - //expect atleast two ** - if (dynType_type(argument->type) == DYN_TYPE_TYPED_POINTER) { - dyn_type *subType = NULL; - status = dynType_typedPointer_getTypedType(argument->type, &subType); - if (status == OK && dynType_type(subType) != DYN_TYPE_TYPED_POINTER) { - status = ERROR; - } - } else { - status = ERROR; - } - } - return status; -} static int dynFunction_initCif(dyn_function_type *dynFunc) { int status = 0; @@ -341,18 +288,3 @@ dyn_type * dynFunction_returnType(dyn_function_type *dynFunction) { return dynFunction->funcReturn; } -int dynFunction_argumentMetaInfoForIndex(dyn_function_type *dynFunc, int argumentNr) { - int argType = DYN_FUNCTION_ARG_META_UNKNOWN_TYPE; - int index = 0; - dyn_function_argument_type *entry = NULL; - TAILQ_FOREACH(entry, &dynFunc->arguments, entries) { - if (index == argumentNr) { - argType = entry->argumentType; - break; - } - index +=1; - } - return argType; -} - - http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h index e99bc7a..de8853c 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h @@ -10,23 +10,16 @@ /** * Uses the following schema - * (Name)([ArgType]*)Type + * (Name)([Type]*)Type * - * ArgType = (Type|PreAllocatedOutputType|OutputType) - * PreAllocatedOutputType = ^(Type) #Note must be *(Type) - * OutputType = ~(Type) #Note must be **(Type) - * e.g add(DD)D or sum({[D[D setA setB})D + * Dyn fynction argument meta (am) as meta info, with the following possible values + * am=handle #void pointer for the handle + * am=pre #output pointer with memory preallocated + * am=out #output pointer */ typedef struct _dyn_function_type dyn_function_type; -#define DYN_FUNCTION_ARG_META_UNKNOWN_TYPE 0 -#define DYN_FUNCTION_ARG_META_INPUT_TYPE 1 -#define DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE 2 -#define DYN_FUNCTION_ARG_META_OUTPUT_TYPE 3 -#define DYN_FUNCTION_ARG_META_HANDLE_TYPE 4 -//TODO input/output types? - DFI_SETUP_LOG_HEADER(dynFunction); int dynFunction_parse(FILE *descriptorStream, struct types_head *refTypes, dyn_function_type **dynFunc); @@ -35,7 +28,6 @@ int dynFunction_parseWithStr(const char *descriptor, struct types_head *refTypes int dynFunction_nrOfArguments(dyn_function_type *dynFunc); dyn_type *dynFunction_argumentTypeForIndex(dyn_function_type *dynFunc, int argumentNr); dyn_type * dynFunction_returnType(dyn_function_type *dynFunction); -int dynFunction_argumentMetaInfoForIndex(dyn_function_type *dynFunc, int argumentNr); void dynFunction_destroy(dyn_function_type *dynFunc); int dynFunction_call(dyn_function_type *dynFunc, void(*fn)(void), void *returnValue, void **argValues); http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c index 6396d1c..aae7ebc 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c @@ -49,12 +49,22 @@ void dynType_freeComplexType(dyn_type *type, void *loc); void dynType_deepFree(dyn_type *type, void *loc, bool alsoDeleteSelf); void dynType_freeSequenceType(dyn_type *type, void *seqLoc); +static int dynType_parseMetaInfo(FILE *stream, dyn_type *type); + struct generic_sequence { uint32_t cap; uint32_t len; void *buf; }; +TAILQ_HEAD(meta_properties_head, meta_entry); +struct meta_entry { + char *name; + char *value; + TAILQ_ENTRY(meta_entry) entries; +}; + + struct _dyn_type { char *name; char descriptor; @@ -63,6 +73,7 @@ struct _dyn_type { dyn_type *parent; struct types_head *referenceTypes; //NOTE: not owned struct types_head nestedTypesHead; + struct meta_properties_head metaProperties; union { struct { struct complex_type_entries_head entriesHead; @@ -119,6 +130,7 @@ static int dynType_parseWithStream(FILE *stream, const char *name, dyn_type *par type->type = DYN_TYPE_INVALID; type->referenceTypes = refTypes; TAILQ_INIT(&type->nestedTypesHead); + TAILQ_INIT(&type->metaProperties); if (name != NULL) { type->name = strdup(name); if (type->name == NULL) { @@ -170,6 +182,12 @@ static int dynType_parseAny(FILE *stream, dyn_type *type) { case 't' : status = dynType_parseText(stream, type); break; + case '#' : + status = dynType_parseMetaInfo(stream, type); + if (status == OK) { + status = dynType_parseAny(stream, type); + } + break; default : status = dynType_parseSimple(c, type); break; @@ -178,6 +196,46 @@ static int dynType_parseAny(FILE *stream, dyn_type *type) { return status; } +static int dynType_parseMetaInfo(FILE *stream, dyn_type *type) { + int status = OK; + char *name = NULL; + char *value = NULL; + + struct meta_entry *entry = calloc(1, sizeof(*entry)); + if (entry == NULL) { + status = ERROR; + } + + if (status == OK) { + status = dynCommon_parseName(stream, &name); + } + + if (status == OK) { + status = dynCommon_eatChar(stream, '='); + } + + if (status == OK) { + status = dynCommon_parseName(stream, &value); + } + + if (status == OK) { + status = dynCommon_eatChar(stream, ';'); + } + + if (status == OK) { + entry->name = name; + entry->value = value; + TAILQ_INSERT_TAIL(&type->metaProperties, entry, entries); + LOG_DEBUG("Added meta properties '%s':'%s'", name, value) + } else { + free(name); + free(value); + free(entry); + } + + return status; +} + static int dynType_parseText(FILE *stream, dyn_type *type) { int status = OK; type->type = DYN_TYPE_TEXT; @@ -205,6 +263,7 @@ static int dynType_parseComplex(FILE *stream, dyn_type *type) { entry->type->parent = type; entry->type->type = DYN_TYPE_INVALID; TAILQ_INIT(&entry->type->nestedTypesHead); + TAILQ_INIT(&entry->type->metaProperties); TAILQ_INSERT_TAIL(&type->complex.entriesHead, entry, entries); status = dynType_parseAny(stream, entry->type); } else { @@ -281,6 +340,7 @@ static int dynType_parseNestedType(FILE *stream, dyn_type *type) { entry->type->parent = type; entry->type->type = DYN_TYPE_INVALID; TAILQ_INIT(&entry->type->nestedTypesHead); + TAILQ_INIT(&entry->type->metaProperties); TAILQ_INSERT_TAIL(&type->nestedTypesHead, entry, entries); status = dynCommon_parseName(stream, &name); entry->type->name = name; @@ -324,6 +384,7 @@ static int dynType_parseReference(FILE *stream, dyn_type *type) { subType->parent = type; subType->type = DYN_TYPE_INVALID; TAILQ_INIT(&subType->nestedTypesHead); + TAILQ_INIT(&subType->metaProperties); status = dynType_parseRefByValue(stream, subType); } else { status = MEM_ERROR; @@ -445,6 +506,17 @@ static void dynType_clear(dyn_type *type) { free(tmp); } + struct meta_entry *mEntry = TAILQ_FIRST(&type->metaProperties);; + struct meta_entry *next = NULL; + while (mEntry != NULL) { + next = TAILQ_NEXT(mEntry, entries); + if (mEntry != NULL) { + free(mEntry->name); + free(mEntry->value); + } + mEntry = next; + } + switch (type->type) { case DYN_TYPE_COMPLEX : dynType_clearComplex(type); @@ -724,6 +796,19 @@ int dynType_descriptorType(dyn_type *type) { return type->descriptor; } +const char * dynType_getMetaInfo(dyn_type *type, const char *name) { + const char *result = NULL; + struct meta_entry *entry = NULL; + TAILQ_FOREACH(entry, &type->metaProperties, entries) { + LOG_DEBUG("Checking '%s'", entry->name); + if (strcmp(entry->name, name) == 0) { + result = entry->value; + break; + } + } + return result; +} + ffi_type *dynType_ffiType(dyn_type *type) { if (type->type == DYN_TYPE_REF) { return type->ref.ref->ffiType; http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.h ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.h index 2058c41..e759dc2 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.h +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.h @@ -21,7 +21,7 @@ /* Description string * - * Type = [TypeDef]* (SimpleType | ComplexType | SequenceType | TypedPointer | PointerReference ) [TypeDef]* [Annotation]* + * Type = [TypeDef]* (MetaInfo)* (SimpleType | ComplexType | SequenceType | TypedPointer | PointerReference ) [TypeDef]* * Name = alpha[(alpha|numeric)*] * SPACE = ' ' * @@ -63,8 +63,10 @@ * TypedPointer * *(Type) * - * Annotation TODO - * <(Name)=(Value)> + * MetaInfo TODO + * #Name=Value; + * + * * * examples * "{DDII a b c d}" -> struct { double a; double b; int c; int d; }; @@ -111,7 +113,8 @@ void dynType_print(dyn_type *type, FILE *stream); size_t dynType_size(dyn_type *type); int dynType_type(dyn_type *type); int dynType_descriptorType(dyn_type *type); -ffi_type *dynType_ffiType(dyn_type *type); +ffi_type * dynType_ffiType(dyn_type *type); +const char * dynType_getMetaInfo(dyn_type *type, const char *name); //complexType int dynType_complex_indexForName(dyn_type *type, const char *name); http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.c new file mode 100644 index 0000000..8a2f15c --- /dev/null +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.c @@ -0,0 +1,235 @@ +/* + * Licensed under Apache License v2. See LICENSE for more information. + */ +#include "json_rpc.h" +#include "json_serializer.h" +#include "dyn_type.h" +#include "dyn_interface.h" + +#include +#include +#include +#include + + +static int OK = 0; +static int ERROR = 1; + +DFI_SETUP_LOG(jsonRpc); + +typedef void (*gen_func_type)(void); + +struct generic_service_layout { + void *handle; + gen_func_type methods[]; +}; + +int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, char **out) { + int status = OK; + + LOG_DEBUG("Parsing data: %s\n", request); + json_error_t error; + json_t *js_request = json_loads(request, 0, &error); + json_t *arguments = NULL; + const char *sig; + if (js_request) { + if (json_unpack(js_request, "{s:s}", "m", &sig) != 0) { + LOG_ERROR("Got json error '%s'\n", error.text); + } else { + arguments = json_object_get(js_request, "a"); + } + } else { + LOG_ERROR("Got json error '%s' for '%s'\n", error.text, request); + return 0; + } + + LOG_DEBUG("Looking for method %s\n", sig); + struct methods_head *methods = NULL; + dynInterface_methods(intf, &methods); + struct method_entry *entry = NULL; + struct method_entry *method = NULL; + TAILQ_FOREACH(entry, methods, entries) { + if (strcmp(sig, entry->id) == 0) { + method = entry; + break; + } + } + + if (method == NULL) { + status = ERROR; + LOG_ERROR("Cannot find method with sig '%s'", sig); + } else { + LOG_DEBUG("RSA: found method '%s'\n", entry->id); + } + + void (*fp)(void) = NULL; + void *handle = NULL; + if (status == OK) { + struct generic_service_layout *serv = service; + handle = serv->handle; + fp = serv->methods[method->index]; + } + + dyn_function_type *func = NULL; + int nrOfArgs = 0; + if (status == OK) { + nrOfArgs = dynFunction_nrOfArguments(entry->dynFunc); + func = entry->dynFunc; + } + + void *args[nrOfArgs]; + + json_t *value = NULL; + + int i; + int index = 0; + for (i = 0; i < nrOfArgs; i += 1) { + dyn_type *argType = dynFunction_argumentTypeForIndex(func, i); + const char *argMeta = dynType_getMetaInfo(argType, "am"); + if (argMeta == NULL) { + printf("setting std for %i\n", i); + value = json_array_get(arguments, index++); + status = jsonSerializer_deserializeJson(argType, value, &(args[i])); + } else if (strcmp(argMeta, "pre") == 0) { + printf("setting pre alloc output for %i\n", i); + dynType_alloc(argType, &args[i]); + + } else if ( strcmp(argMeta, "out") == 0) { + printf("setting output for %i\n", i); + args[i] = NULL; + } else if (strcmp(argMeta, "handle") == 0) { + printf("setting handle for %i\n", i); + args[i] = &handle; + } + + if (status != OK) { + break; + } + } + json_decref(js_request); + + + //TODO assert return type is native int + int returnVal = 0; + dynFunction_call(func, fp, (void *)&returnVal, args); + printf("done calling\n"); + double **r = args[2]; + printf("result ptrptr is %p, result ptr %p, result is %f\n", r, *r, **r); + + + json_t *jsonResult = NULL; + for (i = 0; i < nrOfArgs; i += 1) { + dyn_type *argType = dynFunction_argumentTypeForIndex(func, i); + const char *argMeta = dynType_getMetaInfo(argType, "am"); + if (argMeta == NULL) { + //ignore + } else if (strcmp(argMeta, "pre") == 0) { + if (status == OK) { + status = jsonSerializer_serializeJson(argType, args[i], &jsonResult); + } + } else if (strcmp(argMeta, "out") == 0) { + printf("TODO\n"); + assert(false); + } + + if (status != OK) { + break; + } + } + + char *response = NULL; + if (status == OK) { + LOG_DEBUG("creating payload\n"); + json_t *payload = json_object(); + json_object_set_new(payload, "r", jsonResult); + response = json_dumps(payload, JSON_DECODE_ANY); + json_decref(payload); + LOG_DEBUG("status ptr is %p. response if '%s'\n", status, response); + } + + if (status == OK) { + *out = response; + } else { + if (response != NULL) { + free(response); + } + } + + //TODO free args (created by jsonSerializer and dynType_alloc) (dynType_free) + return status; +} + +int jsonRpc_prepareInvokeRequest(dyn_function_type *func, const char *id, void *args[], char **out) { + int status = OK; + + + LOG_DEBUG("Calling remote function '%s'\n", id); + json_t *invoke = json_object(); + json_object_set(invoke, "m", json_string(id)); + + json_t *arguments = json_array(); + json_object_set_new(invoke, "a", arguments); + + int i; + int nrOfArgs = dynFunction_nrOfArguments(func); + for (i = 0; i < nrOfArgs; i +=1) { + dyn_type *type = dynFunction_argumentTypeForIndex(func, i); + const char *argMeta = dynType_getMetaInfo(type, "am"); + if (argMeta == NULL) { + json_t *val = NULL; + + int rc = jsonSerializer_serializeJson(type, args[i], &val); + if (rc == 0) { + json_array_append_new(arguments, val); + } else { + status = ERROR; + break; + } + } else { + //skip handle / output types + } + } + + char *invokeStr = json_dumps(invoke, JSON_DECODE_ANY); + json_decref(invoke); + + if (status == OK) { + *out = invokeStr; + } + + return status; +} + +int jsonRpc_handleReply(dyn_function_type *func, const char *reply, void *args[]) { + int status = 0; + + json_t *replyJson = json_loads(reply, JSON_DECODE_ANY, NULL); //TODO check + json_t *result = json_object_get(replyJson, "r"); //TODO check + + LOG_DEBUG("replyJson ptr is %p and result ptr is %p\n", replyJson, result); + + int nrOfArgs = dynFunction_nrOfArguments(func); + int i; + for (i = 0; i < nrOfArgs; i += 1) { + dyn_type *argType = dynFunction_argumentTypeForIndex(func, i); + const char *argMeta = dynType_getMetaInfo(argType, "am"); + if (argMeta == NULL) { + //skip + } else if (strcmp(argMeta, "pre") == 0) { + dyn_type *subType = NULL; + dynType_typedPointer_getTypedType(argType, &subType); + void *tmp = NULL; + size_t size = dynType_size(subType); + status = jsonSerializer_deserializeJson(subType, result, &tmp); + void **out = (void **)args[i]; + memcpy(*out, tmp, size); + dynType_free(subType, tmp); + } else if (strcmp(argMeta, "out") == 0) { + assert(false); //TODO + } + } + + json_decref(replyJson); + + return status; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.h ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.h new file mode 100644 index 0000000..60811ac --- /dev/null +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.h @@ -0,0 +1,22 @@ +/** + * Licensed under Apache License v2. See LICENSE for more information. + */ +#ifndef __JSON_RPC_H_ +#define __JSON_RPC_H_ + +#include +#include "dfi_log_util.h" +#include "dyn_type.h" +#include "dyn_function.h" +#include "dyn_interface.h" + +//logging +DFI_SETUP_LOG_HEADER(jsonRpc); + +int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, char **out); + + +int jsonRpc_prepareInvokeRequest(dyn_function_type *func, const char *id, void *args[], char **out); +int jsonRpc_handleReply(dyn_function_type *func, const char *reply, void *args[]); + +#endif http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c index a689483..30f5296 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c @@ -27,13 +27,6 @@ static int ERROR = 1; DFI_SETUP_LOG(jsonSerializer); -typedef void (*gen_func_type)(void); - -struct generic_service_layout { - void *handle; - gen_func_type methods[]; -}; - int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result) { assert(dynType_type(type) == DYN_TYPE_COMPLEX); int status = 0; @@ -422,210 +415,4 @@ static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t **out } return status; -} - -int jsonSerializer_call(dyn_interface_type *intf, void *service, const char *request, char **out) { - int status = OK; - - LOG_DEBUG("Parsing data: %s\n", request); - json_error_t error; - json_t *js_request = json_loads(request, 0, &error); - json_t *arguments = NULL; - const char *sig; - if (js_request) { - if (json_unpack(js_request, "{s:s}", "m", &sig) != 0) { - LOG_ERROR("Got json error '%s'\n", error.text); - } else { - arguments = json_object_get(js_request, "a"); - } - } else { - LOG_ERROR("Got json error '%s' for '%s'\n", error.text, request); - return 0; - } - - LOG_DEBUG("Looking for method %s\n", sig); - struct methods_head *methods = NULL; - dynInterface_methods(intf, &methods); - struct method_entry *entry = NULL; - struct method_entry *method = NULL; - TAILQ_FOREACH(entry, methods, entries) { - if (strcmp(sig, entry->id) == 0) { - method = entry; - break; - } - } - - if (method == NULL) { - status = ERROR; - LOG_ERROR("Cannot find method with sig '%s'", sig); - } else { - LOG_DEBUG("RSA: found method '%s'\n", entry->id); - } - - void (*fp)(void) = NULL; - void *handle = NULL; - if (status == OK) { - struct generic_service_layout *serv = service; - handle = serv->handle; - fp = serv->methods[method->index]; - } - - dyn_function_type *func = NULL; - int nrOfArgs = 0; - if (status == OK) { - nrOfArgs = dynFunction_nrOfArguments(entry->dynFunc); - func = entry->dynFunc; - } - - void *args[nrOfArgs]; - - json_t *value = NULL; - - int i; - int index = 0; - for (i = 0; i < nrOfArgs; i += 1) { - int metaInfo = dynFunction_argumentMetaInfoForIndex(func, i); - dyn_type *argType = dynFunction_argumentTypeForIndex(func, i); - if (metaInfo == DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE) { - printf("setting pre alloc output for %i\n", i); - dynType_alloc(argType, &args[i]); - - } else if ( metaInfo == DYN_FUNCTION_ARG_META_OUTPUT_TYPE) { - printf("setting output for %i\n", i); - args[i] = NULL; - } else if (metaInfo == DYN_FUNCTION_ARG_META_HANDLE_TYPE) { - printf("setting handle for %i\n", i); - args[i] = &handle; - } else { - printf("setting std for %i\n", i); - value = json_array_get(arguments, index++); - status = jsonSerializer_deserializeJson(argType, value, &(args[i])); - } - - if (status != OK) { - break; - } - } - json_decref(js_request); - - - //TODO assert return type is native int - int returnVal = 0; - dynFunction_call(func, fp, (void *)&returnVal, args); - printf("done calling\n"); - double **r = args[2]; - printf("result ptrptr is %p, result ptr %p, result is %f\n", r, *r, **r); - - - json_t *jsonResult = NULL; - for (i = 0; i < nrOfArgs; i += 1) { - int metaInfo = dynFunction_argumentMetaInfoForIndex(func, i); - dyn_type *argType = dynFunction_argumentTypeForIndex(func, i); - if (metaInfo == DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE) { - if (status == OK) { - status = jsonSerializer_serializeJson(argType, args[i], &jsonResult); - } - } else if (metaInfo == DYN_FUNCTION_ARG_META_OUTPUT_TYPE) { - printf("TODO\n"); - assert(false); - } - - if (status != OK) { - break; - } - } - - char *response = NULL; - if (status == OK) { - LOG_DEBUG("creating payload\n"); - json_t *payload = json_object(); - json_object_set_new(payload, "r", jsonResult); - response = json_dumps(payload, JSON_DECODE_ANY); - json_decref(payload); - LOG_DEBUG("status ptr is %p. response if '%s'\n", status, response); - } - - if (status == OK) { - *out = response; - } else { - if (response != NULL) { - free(response); - } - } - - //TODO free args (created by jsonSerializer and dynType_alloc) (dynType_free) - return status; -} - -int jsonSerializer_prepareInvokeRequest(dyn_function_type *func, const char *id, void *args[], char **out) { - int status = OK; - - - LOG_DEBUG("Calling remote function '%s'\n", id); - json_t *invoke = json_object(); - json_object_set(invoke, "m", json_string(id)); - - json_t *arguments = json_array(); - json_object_set_new(invoke, "a", arguments); - - int i; - int nrOfArgs = dynFunction_nrOfArguments(func); - for (i = 0; i < nrOfArgs; i +=1) { - if (dynFunction_argumentMetaInfoForIndex(func, i) == DYN_FUNCTION_ARG_META_INPUT_TYPE) { - json_t *val = NULL; - dyn_type *type = dynFunction_argumentTypeForIndex(func, i); - int rc = jsonSerializer_serializeJson(type, args[i], &val); - if (rc == 0) { - json_array_append_new(arguments, val); - } else { - status = ERROR; - break; - } - } else { - //skip handle / output types - } - } - - char *invokeStr = json_dumps(invoke, JSON_DECODE_ANY); - json_decref(invoke); - - if (status == OK) { - *out = invokeStr; - } - - return status; -} - -int jsonSerializer_handleReply(dyn_function_type *func, const char *reply, void *args[]) { - int status = 0; - - json_t *replyJson = json_loads(reply, JSON_DECODE_ANY, NULL); //TODO check - json_t *result = json_object_get(replyJson, "r"); //TODO check - - LOG_DEBUG("replyJson ptr is %p and result ptr is %p\n", replyJson, result); - - int nrOfArgs = dynFunction_nrOfArguments(func); - int i; - for (i = 0; i < nrOfArgs; i += 1) { - dyn_type *argType = dynFunction_argumentTypeForIndex(func, i); - int metaInf = dynFunction_argumentMetaInfoForIndex(func, i); - if (metaInf == DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE) { - dyn_type *subType = NULL; - dynType_typedPointer_getTypedType(argType, &subType); - void *tmp = NULL; - size_t size = dynType_size(subType); - status = jsonSerializer_deserializeJson(subType, result, &tmp); - void **out = (void **)args[i]; - memcpy(*out, tmp, size); - dynType_free(subType, tmp); - } else if (metaInf == DYN_FUNCTION_ARG_META_OUTPUT_TYPE) { - assert(false); //TODO - } else { - //skip handle and input types - } - } - - json_decref(replyJson); - - return status; } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h index 6e7ee7d..9976938 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h @@ -19,8 +19,4 @@ int jsonSerializer_deserializeJson(dyn_type *type, json_t *input, void **result) int jsonSerializer_serialize(dyn_type *type, void *input, char **output); int jsonSerializer_serializeJson(dyn_type *type, void *input, json_t **out); -int jsonSerializer_call(dyn_interface_type *intf, void *service, const char *request, char **out); - -int jsonSerializer_prepareInvokeRequest(dyn_function_type *func, const char *id, void *args[], char **out); -int jsonSerializer_handleReply(dyn_function_type *func, const char *reply, void *args[]); #endif http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt index 50325ab..13477c4 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt @@ -11,6 +11,7 @@ add_executable(test_dfi dyn_closure_tests.cpp dyn_interface_tests.cpp json_serializer_tests.cpp + json_rpc_tests.cpp run_tests.cpp ) target_link_libraries(test_dfi dfi ${CPPUTEST_LIBRARY}) http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_function_tests.cpp ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_function_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_function_tests.cpp index cb4e13b..413f6e9 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_function_tests.cpp +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_function_tests.cpp @@ -166,40 +166,6 @@ extern "C" { dynFunction_destroy(dynFunc); } - - void test_meta(void) { - int rc; - dyn_function_type *func = NULL; - - const char *descriptor1 = "sqrt(D^*D~**D#P)V"; - rc = dynFunction_parseWithStr(descriptor1, NULL, &func); - CHECK_EQUAL(0, rc); - CHECK_EQUAL(DYN_FUNCTION_ARG_META_INPUT_TYPE, dynFunction_argumentMetaInfoForIndex(func, 0)); - CHECK_EQUAL(DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE, dynFunction_argumentMetaInfoForIndex(func, 1)); - CHECK_EQUAL(DYN_FUNCTION_ARG_META_OUTPUT_TYPE, dynFunction_argumentMetaInfoForIndex(func, 2)); - CHECK_EQUAL(DYN_FUNCTION_ARG_META_HANDLE_TYPE, dynFunction_argumentMetaInfoForIndex(func, 3)); - CHECK_EQUAL(DYN_FUNCTION_ARG_META_UNKNOWN_TYPE, dynFunction_argumentMetaInfoForIndex(func, 4)); - dynFunction_destroy(func); - - const char *descriptor2 = "sqrt(D~*D)V"; - rc = dynFunction_parseWithStr(descriptor2, NULL, &func); - CHECK(rc != 0); - - const char *descriptor3 = "sqrt(D~***D)V"; - rc = dynFunction_parseWithStr(descriptor3, NULL, &func); - CHECK_EQUAL(0, rc); - dynFunction_destroy(func); - - - const char *descriptor4 = "sqrt(D^D)V"; - rc = dynFunction_parseWithStr(descriptor4, NULL, &func); - CHECK(rc != 0); - - const char *descriptor5 = "sqrt(D^***D)V"; - rc = dynFunction_parseWithStr(descriptor5, NULL, &func); - CHECK_EQUAL(0, rc); - dynFunction_destroy(func); - } } TEST_GROUP(DynFunctionTests) { @@ -224,8 +190,4 @@ TEST(DynFunctionTests, DynFuncAccTest) { TEST(DynFunctionTests, DynFuncTest3) { test_example3(); -} - -TEST(DynFunctionTests, DynFuncTestMeta) { - test_meta(); } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_type_tests.cpp ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_type_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_type_tests.cpp index 96f64fa..2f05bd1 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_type_tests.cpp +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/dyn_type_tests.cpp @@ -38,7 +38,7 @@ extern "C" { TEST_GROUP(DynTypeTests) { void setup() { - dynType_logSetup(stdLog, NULL, 0); + dynType_logSetup(stdLog, NULL, 4); } }; @@ -188,3 +188,25 @@ TEST(DynTypeTests, AssignTest3) { dynType_destroy(type); } +TEST(DynTypeTests, MetaInfoTest) { + dyn_type *type = NULL; + int rc = 0; + rc = dynType_parseWithStr("#a=t;{DD#longname=longvalue;D a b c}", NULL, NULL, &type); + //rc = dynType_parseWithStr("{DDD a b c}", NULL, NULL, &type); + + CHECK_EQUAL(0, rc); + + const char *val = NULL; + val = dynType_getMetaInfo(type, "a"); + CHECK(val != NULL); + CHECK(strcmp("t", val) == 0); + + val = dynType_getMetaInfo(type, "longname"); + CHECK(val == NULL); + + val = dynType_getMetaInfo(type, "nonexisting"); + CHECK(val == NULL); + + dynType_destroy(type); +} + http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/json_rpc_tests.cpp ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/json_rpc_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/json_rpc_tests.cpp new file mode 100644 index 0000000..52b7386 --- /dev/null +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/json_rpc_tests.cpp @@ -0,0 +1,61 @@ +/** + * Licensed under Apache License v2. See LICENSE for more information. + */ +#include +#include "CppUTest/CommandLineTestRunner.h" + +extern "C" { +#include +#include +#include +#include +#include + +#include + +#include "dyn_common.h" +#include "dyn_type.h" +#include "json_serializer.h" +#include "json_rpc.h" + +static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) { + va_list ap; + const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"}; + fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line); + va_start(ap, msg); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); +} + + + void handleTest(void) { + dyn_function_type *dynFunc = NULL; + int rc = dynFunction_parseWithStr("add(#at=h;PDD#at=pa;*D)N", NULL, &dynFunc); + CHECK_EQUAL(0, rc); + + //TODO jsonRpc_handleReply(dynFunc, ) + } + + void prepareTest(void) { + + } + +} + +TEST_GROUP(JsonRpcTests) { + void setup() { + int lvl = 1; + dynCommon_logSetup(stdLog, NULL, lvl); + dynType_logSetup(stdLog, NULL,lvl); + jsonSerializer_logSetup(stdLog, NULL, lvl); + } +}; + +TEST(JsonRpcTests, handleTest) { + handleTest(); +} + +TEST(JsonRpcTests, prepareTest) { + prepareTest(); +} + http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c index b5f0fec..9bc5b08 100644 --- a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c +++ b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "export_registration_dfi.h" struct export_reference { @@ -100,8 +101,8 @@ celix_status_t exportRegistration_create(log_helper_pt helper, void (*closedCall if (status == CELIX_SUCCESS) { service_tracker_customizer_pt cust = NULL; - status = serviceTrackerCustomizer_create(reg, NULL, exportRegistration_addServ, NULL, - exportRegistration_removeServ, &cust); + status = serviceTrackerCustomizer_create(reg, NULL, (void *) exportRegistration_addServ, NULL, + (void *) exportRegistration_removeServ, &cust); if (status == CELIX_SUCCESS) { char filter[32]; snprintf(filter, 32, "(service.id=%s)", servId); @@ -124,7 +125,7 @@ celix_status_t exportRegistration_call(export_registration_pt export, char *data *responseLength = -1; celixThreadMutex_lock(&export->mutex); - status = jsonSerializer_call(export->intf, export->service, data, responseOut); + status = jsonRpc_call(export->intf, export->service, data, responseOut); celixThreadMutex_unlock(&export->mutex); return status; @@ -168,7 +169,7 @@ static void exportRegistration_addServ(export_registration_pt reg, service_refer static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service) { celixThreadMutex_lock(®->mutex); if (reg->service == service) { - reg->service == NULL; + reg->service = NULL; } celixThreadMutex_unlock(®->mutex); } http://git-wip-us.apache.org/repos/asf/celix/blob/837926e6/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c index 9667fa9..9c4d717 100644 --- a/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c +++ b/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c @@ -1,5 +1,6 @@ #include #include +#include #include "json_serializer.h" #include "dyn_interface.h" #include "import_registration.h" @@ -230,7 +231,7 @@ static void importRegistration_proxyFunc(void *userData, void *args[], void *ret char *invokeRequest = NULL; if (status == CELIX_SUCCESS) { - status = jsonSerializer_prepareInvokeRequest(entry->dynFunc, entry->id, args, &invokeRequest); + status = jsonRpc_prepareInvokeRequest(entry->dynFunc, entry->id, args, &invokeRequest); printf("Need to send following json '%s'\n", invokeRequest); } @@ -243,7 +244,7 @@ static void importRegistration_proxyFunc(void *userData, void *args[], void *ret if (rc == 0) { printf("handling reply\n"); - status = jsonSerializer_handleReply(entry->dynFunc, reply, args); + status = jsonRpc_handleReply(entry->dynFunc, reply, args); } *(int *) returnVal = rc;