You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2017/11/20 20:33:27 UTC

[30/46] celix git commit: CELIX-417: Initial refactoring for CMake usage

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/src/json_rpc.c
----------------------------------------------------------------------
diff --git a/dfi/src/json_rpc.c b/dfi/src/json_rpc.c
new file mode 100644
index 0000000..f2b0c56
--- /dev/null
+++ b/dfi/src/json_rpc.c
@@ -0,0 +1,341 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#include "json_rpc.h"
+#include "json_serializer.h"
+#include "dyn_type.h"
+#include "dyn_interface.h"
+#include <jansson.h>
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include <ffi.h>
+
+
+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;
+
+	dyn_type* returnType = NULL;
+
+	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 if (status == OK) {
+		LOG_DEBUG("RSA: found method '%s'\n", entry->id);
+		returnType = dynFunction_returnType(method->dynFunc);
+	}
+
+	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;
+
+	void *ptr = NULL;
+	void *ptrToPtr = &ptr;
+
+	for (i = 0; i < nrOfArgs; i += 1) {
+		dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
+		enum dyn_function_argument_meta  meta = dynFunction_argumentMetaForIndex(func, i);
+		if (meta == DYN_FUNCTION_ARGUMENT_META__STD) {
+			value = json_array_get(arguments, index++);
+			status = jsonSerializer_deserializeJson(argType, value, &(args[i]));
+		} else if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
+			dynType_alloc(argType, &args[i]);
+		} else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
+			args[i] = &ptrToPtr;
+		} else if (meta == DYN_FUNCTION_ARGUMENT_META__HANDLE) {
+			args[i] = &handle;
+		}
+
+		if (status != OK) {
+			break;
+		}
+	}
+	json_decref(js_request);
+
+	if (status == OK) {
+		if (dynType_descriptorType(returnType) != 'N') {
+			//NOTE To be able to handle exception only N as returnType is supported
+			LOG_ERROR("Only interface methods with a native int are supported. Found type '%c'", (char)dynType_descriptorType(returnType));
+			status = ERROR;
+		}
+	}
+
+	ffi_sarg returnVal = 1;
+
+	if (status == OK) {
+		status = dynFunction_call(func, fp, (void *) &returnVal, args);
+	}
+
+	int funcCallStatus = (int)returnVal;
+	if (funcCallStatus != 0) {
+		LOG_WARNING("Error calling remote endpoint function, got error code %i", funcCallStatus);
+	}
+
+	json_t *jsonResult = NULL;
+	for(i = 0; i < nrOfArgs; i += 1) {
+		dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
+		enum dyn_function_argument_meta  meta = dynFunction_argumentMetaForIndex(func, i);
+		if (meta == DYN_FUNCTION_ARGUMENT_META__STD) {
+			dynType_free(argType, args[i]);
+		}
+	}
+
+	if (funcCallStatus == 0 && status == OK) {
+		for (i = 0; i < nrOfArgs; i += 1) {
+			dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
+			enum dyn_function_argument_meta  meta = dynFunction_argumentMetaForIndex(func, i);
+			if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
+				if (status == OK) {
+					status = jsonSerializer_serializeJson(argType, args[i], &jsonResult);
+				}
+				dynType_free(argType, args[i]);
+			} else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
+				if (ptr != NULL) {
+					dyn_type *typedType = NULL;
+					if (status == OK) {
+						status = dynType_typedPointer_getTypedType(argType, &typedType);
+					}
+					if (dynType_descriptorType(typedType) == 't') {
+						status = jsonSerializer_serializeJson(typedType, (void*) &ptr, &jsonResult);
+						free(ptr);
+					} else {
+						dyn_type *typedTypedType = NULL;
+						if (status == OK) {
+							status = dynType_typedPointer_getTypedType(typedType, &typedTypedType);
+						}
+
+						if(status == OK){
+							status = jsonSerializer_serializeJson(typedTypedType, ptr, &jsonResult);
+						}
+
+						if (status == OK) {
+							dynType_free(typedTypedType, ptr);
+						}
+					}
+
+				} else {
+					LOG_DEBUG("Output ptr is null");
+				}
+			}
+
+			if (status != OK) {
+				break;
+			}
+		}
+	}
+
+	char *response = NULL;
+	if (status == OK) {
+		LOG_DEBUG("creating payload\n");
+		json_t *payload = json_object();
+		if (funcCallStatus == 0) {
+			if (jsonResult == NULL) {
+				//ignore -> no result
+			} else {
+				LOG_DEBUG("Setting result payload");
+				json_object_set_new(payload, "r", jsonResult);
+			}
+		} else {
+			LOG_DEBUG("Setting error payload");
+			json_object_set_new(payload, "e", json_integer(funcCallStatus));
+		}
+		response = json_dumps(payload, JSON_DECODE_ANY);
+		json_decref(payload);
+		LOG_DEBUG("status ptr is %p. response is '%s'\n", status, response);
+	}
+
+	if (status == OK) {
+		*out = response;
+	} else {
+		free(response);
+	}
+
+	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_new(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);
+		enum dyn_function_argument_meta  meta = dynFunction_argumentMetaForIndex(func, i);
+		if (meta == DYN_FUNCTION_ARGUMENT_META__STD) {
+			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 = OK;
+
+	json_error_t error;
+	json_t *replyJson = json_loads(reply, JSON_DECODE_ANY, &error);
+	if (replyJson == NULL) {
+		status = ERROR;
+		LOG_ERROR("Error parsing json '%s', got error '%s'", reply, error.text);
+	}
+
+	json_t *result = NULL;
+	if (status == OK) {
+		result = json_object_get(replyJson, "r"); //TODO check
+		if (result == NULL) {
+			status = ERROR;
+			LOG_ERROR("Cannot find r entry in json reply '%s'", reply);
+		}
+	}
+
+	if (status == OK) {
+		int nrOfArgs = dynFunction_nrOfArguments(func);
+		int i;
+		for (i = 0; i < nrOfArgs; i += 1) {
+			dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
+			enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
+			if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
+				void *tmp = NULL;
+				void **out = (void **) args[i];
+
+				size_t size = 0;
+
+				if (dynType_descriptorType(argType) == 't') {
+					status = jsonSerializer_deserializeJson(argType, result, &tmp);
+					if(tmp!=NULL){
+						size = strnlen(((char *) *(char**) tmp), 1024 * 1024);
+						memcpy(*out, *(void**) tmp, size);
+					}
+				} else {
+					dynType_typedPointer_getTypedType(argType, &argType);
+					status = jsonSerializer_deserializeJson(argType, result, &tmp);
+					if(tmp!=NULL){
+						size = dynType_size(argType);
+						memcpy(*out, tmp, size);
+					}
+				}
+
+				dynType_free(argType, tmp);
+			} else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
+				dyn_type *subType = NULL;
+
+				dynType_typedPointer_getTypedType(argType, &subType);
+
+				if (dynType_descriptorType(subType) == 't') {
+					void ***out = (void ***) args[i];
+					status = jsonSerializer_deserializeJson(subType, result, *out);
+				} else {
+					dyn_type *subSubType = NULL;
+					dynType_typedPointer_getTypedType(subType, &subSubType);
+					void ***out = (void ***) args[i];
+					status = jsonSerializer_deserializeJson(subSubType, result, *out);
+				}
+			} else {
+				//skip
+			}
+		}
+	}
+
+	json_decref(replyJson);
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/src/json_serializer.c
----------------------------------------------------------------------
diff --git a/dfi/src/json_serializer.c b/dfi/src/json_serializer.c
new file mode 100644
index 0000000..4b78aeb
--- /dev/null
+++ b/dfi/src/json_serializer.c
@@ -0,0 +1,484 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#include "json_serializer.h"
+#include "dyn_type.h"
+#include "dyn_interface.h"
+
+#include <jansson.h>
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+static int jsonSerializer_createType(dyn_type *type, json_t *object, void **result);
+static int jsonSerializer_parseObject(dyn_type *type, json_t *object, void *inst);
+static int jsonSerializer_parseObjectMember(dyn_type *type, const char *name, json_t *val, void *inst);
+static int jsonSerializer_parseSequence(dyn_type *seq, json_t *array, void *seqLoc);
+static int jsonSerializer_parseAny(dyn_type *type, void *input, json_t *val);
+
+static int jsonSerializer_writeAny(dyn_type *type, void *input, json_t **val);
+
+static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t **val);
+
+static int jsonSerializer_writeSequence(dyn_type *type, void *input, json_t **out);
+
+static int OK = 0;
+static int ERROR = 1;
+
+DFI_SETUP_LOG(jsonSerializer);
+
+int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result) {
+    assert(dynType_type(type) == DYN_TYPE_COMPLEX || dynType_type(type) == DYN_TYPE_SEQUENCE);
+    int status = 0;
+
+    json_error_t error;
+    json_t *root = json_loads(input, JSON_DECODE_ANY, &error);
+
+    if (root != NULL) {
+        status = jsonSerializer_deserializeJson(type, root, result);
+        json_decref(root);
+    } else {
+        status = ERROR;
+        LOG_ERROR("Error parsing json input '%s'. Error is: %s\n", input, error.text);
+    }
+
+    if (status != OK) {
+        LOG_ERROR("Error cannot deserialize json. Input is '%s'\n", input);
+    }
+    return status;
+}
+
+int jsonSerializer_deserializeJson(dyn_type *type, json_t *input, void **out) {
+    return jsonSerializer_createType(type, input, out);
+}
+
+static int jsonSerializer_createType(dyn_type *type, json_t *val, void **result) {
+    assert(val != NULL);
+    int status = OK;
+    void *inst = NULL;
+
+    if (dynType_descriptorType(type) == 't') {
+        if (json_typeof(val) == JSON_STRING) {
+            inst = strdup(json_string_value(val));
+        } else {
+            status = ERROR;
+            LOG_ERROR("Expected json_string type got %i\n", json_typeof(val));
+        }
+    } else {
+        status = dynType_alloc(type, &inst);
+
+        if (status == OK) {
+            assert(inst != NULL);
+            status = jsonSerializer_parseAny(type, inst, val);
+        }
+    }
+
+    if (status == OK) {
+        *result = inst;
+    }
+    else{
+    	dynType_free(type, inst);
+    }
+
+    return status;
+}
+
+static int jsonSerializer_parseObject(dyn_type *type, json_t *object, void *inst) {
+    assert(object != NULL);
+    int status = 0;
+    json_t *value;
+    const char *key;
+
+    json_object_foreach(object, key, value) {
+        status = jsonSerializer_parseObjectMember(type, key, value, inst);
+        if (status != OK) {
+            break;
+        }
+    }
+
+    return status;
+}
+
+static int jsonSerializer_parseObjectMember(dyn_type *type, const char *name, json_t *val, void *inst) {
+    int status = OK;
+    void *valp = NULL;
+    dyn_type *valType = NULL;
+
+    int index = dynType_complex_indexForName(type, name);
+    if (index < 0) {
+        LOG_ERROR("Cannot find index for member '%s'", name);
+        status = ERROR;
+    }
+
+    if (status == OK) {
+        status = dynType_complex_valLocAt(type, index, inst, &valp);
+    }
+
+    if (status == OK ) {
+        status = dynType_complex_dynTypeAt(type, index, &valType);
+    }
+
+    if (status == OK) {
+        status = jsonSerializer_parseAny(valType, valp, val);
+    }
+
+    return status;
+}
+
+static int jsonSerializer_parseAny(dyn_type *type, void *loc, json_t *val) {
+    int status = OK;
+
+    dyn_type *subType = NULL;
+    char c = dynType_descriptorType(type);
+
+    /*
+    printf("parseAny with descriptor '%c' :", c);
+    json_dumpf(val, stdout, 0); //TODO remove
+    printf("\n");
+     */
+
+    bool *z;            //Z
+    float *f;           //F
+    double *d;          //D
+    char *b;            //B
+    int *n;             //N
+    int16_t *s;         //S
+    int32_t *i;         //I
+    int64_t *l;         //J
+    uint8_t   *ub;      //b
+    uint16_t  *us;      //s
+    uint32_t  *ui;      //i
+    uint64_t  *ul;      //j
+
+    switch (c) {
+        case 'Z' :
+            z = loc;
+            *z = (bool) json_is_true(val);
+            break;
+        case 'F' :
+            f = loc;
+            *f = (float) json_real_value(val);
+            break;
+        case 'D' :
+            d = loc;
+            *d = json_real_value(val);
+            break;
+        case 'N' :
+            n = loc;
+            *n = (int) json_integer_value(val);
+            break;
+        case 'B' :
+            b = loc;
+            *b = (char) json_integer_value(val);
+            break;
+        case 'S' :
+            s = loc;
+            *s = (int16_t) json_integer_value(val);
+            break;
+        case 'I' :
+            i = loc;
+            *i = (int32_t) json_integer_value(val);
+            break;
+        case 'J' :
+            l = loc;
+            *l = (int64_t) json_integer_value(val);
+            break;
+        case 'b' :
+            ub = loc;
+            *ub = (uint8_t) json_integer_value(val);
+            break;
+        case 's' :
+            us = loc;
+            *us = (uint16_t) json_integer_value(val);
+            break;
+        case 'i' :
+            ui = loc;
+            *ui = (uint32_t) json_integer_value(val);
+            break;
+        case 'j' :
+            ul = loc;
+            *ul = (uint64_t) json_integer_value(val);
+            break;
+        case 't' :
+            if (json_is_string(val)) {
+                dynType_text_allocAndInit(type, loc, json_string_value(val));
+            } else {
+                status = ERROR;
+                LOG_ERROR("Expected json string type got %i", json_typeof(val));
+            }
+            break;
+        case '[' :
+            if (json_is_array(val)) {
+                status = jsonSerializer_parseSequence(type, val, loc);
+            } else {
+                status = ERROR;
+                LOG_ERROR("Expected json array type got '%i'", json_typeof(val));
+            }
+            break;
+        case '{' :
+            if (status == OK) {
+                status = jsonSerializer_parseObject(type, val, loc);
+            }
+            break;
+        case '*' :
+            status = dynType_typedPointer_getTypedType(type, &subType);
+            if (status == OK) {
+                status = jsonSerializer_createType(subType, val, (void **) loc);
+            }
+            break;
+        case 'P' :
+            status = ERROR;
+            LOG_WARNING("Untyped pointer are not supported for serialization");
+            break;
+        default :
+            status = ERROR;
+            LOG_ERROR("Error provided type '%c' not supported for JSON\n", dynType_descriptorType(type));
+            break;
+    }
+
+    return status;
+}
+
+static int jsonSerializer_parseSequence(dyn_type *seq, json_t *array, void *seqLoc) {
+    assert(dynType_type(seq) == DYN_TYPE_SEQUENCE);
+    int status = OK;
+
+    size_t size = json_array_size(array);
+    //LOG_DEBUG("Allocating sequence with capacity %zu", size);
+    status = dynType_sequence_alloc(seq, seqLoc, (int) size);
+
+    if (status == OK) {
+        dyn_type *itemType = dynType_sequence_itemType(seq);
+        size_t index;
+        json_t *val;
+        json_array_foreach(array, index, val) {
+            void *valLoc = NULL;
+            status = dynType_sequence_increaseLengthAndReturnLastLoc(seq, seqLoc, &valLoc);
+            //LOG_DEBUG("Got sequence loc %p for index %zu", valLoc, index);
+
+            if (status == OK) {
+                status = jsonSerializer_parseAny(itemType, valLoc, val);
+                if (status != OK) {
+                    break;
+                }
+            }
+        }
+    }
+
+    return status;
+}
+
+int jsonSerializer_serialize(dyn_type *type, const void* input, char **output) {
+    int status = OK;
+
+    json_t *root = NULL;
+    status = jsonSerializer_serializeJson(type, input, &root);
+
+    if (status == OK) {
+        *output = json_dumps(root, JSON_COMPACT);
+        json_decref(root);
+    }
+
+    return status;
+}
+
+int jsonSerializer_serializeJson(dyn_type *type, const void* input, json_t **out) {
+    return jsonSerializer_writeAny(type, (void*)input /*TODO update static function to take const void**/, out);
+}
+
+static int jsonSerializer_writeAny(dyn_type *type, void* input, json_t **out) {
+    int status = OK;
+
+    int descriptor = dynType_descriptorType(type);
+    json_t *val = NULL;
+    dyn_type *subType = NULL;
+
+    bool *z;            //Z
+    float *f;           //F
+    double *d;          //D
+    char *b;            //B
+    int *n;             //N
+    int16_t *s;         //S
+    int32_t *i;         //I
+    int64_t *l;         //J
+    uint8_t   *ub;      //b
+    uint16_t  *us;      //s
+    uint32_t  *ui;      //i
+    uint64_t  *ul;      //j
+
+    switch (descriptor) {
+        case 'Z' :
+            z = input;
+            val = json_boolean((bool)*z);
+            break;
+        case 'B' :
+            b = input;
+            val = json_integer((json_int_t)*b);
+            break;
+        case 'S' :
+            s = input;
+            val = json_integer((json_int_t)*s);
+            break;
+        case 'I' :
+            i = input;
+            val = json_integer((json_int_t)*i);
+            break;
+        case 'J' :
+            l = input;
+            val = json_integer((json_int_t)*l);
+            break;
+        case 'b' :
+            ub = input;
+            val = json_integer((json_int_t)*ub);
+            break;
+        case 's' :
+            us = input;
+            val = json_integer((json_int_t)*us);
+            break;
+        case 'i' :
+            ui = input;
+            val = json_integer((json_int_t)*ui);
+            break;
+        case 'j' :
+            ul = input;
+            val = json_integer((json_int_t)*ul);
+            break;
+        case 'N' :
+            n = input;
+            val = json_integer((json_int_t)*n);
+            break;
+        case 'F' :
+            f = input;
+            val = json_real((double) *f);
+            break;
+        case 'D' :
+            d = input;
+            val = json_real(*d);
+            break;
+        case 't' :
+            val = json_string(*(const char **) input);
+            break;
+        case '*' :
+            status = dynType_typedPointer_getTypedType(type, &subType);
+            if (status == OK) {
+                status = jsonSerializer_writeAny(subType, *(void **)input, &val);
+            }
+            break;
+        case '{' :
+            status = jsonSerializer_writeComplex(type, input, &val);
+            break;
+        case '[' :
+            status = jsonSerializer_writeSequence(type, input, &val);
+            break;
+        case 'P' :
+            LOG_WARNING("Untyped pointer not supported for serialization. ignoring");
+            break;
+        default :
+            LOG_ERROR("Unsupported descriptor '%c'", descriptor);
+            status = ERROR;
+            break;
+    }
+
+    if (status == OK && val != NULL) {
+        *out = val;
+    }
+
+    return status;
+}
+
+static int jsonSerializer_writeSequence(dyn_type *type, void *input, json_t **out) {
+    assert(dynType_type(type) == DYN_TYPE_SEQUENCE);
+    int status = OK;
+
+    json_t *array = json_array();
+    dyn_type *itemType = dynType_sequence_itemType(type);
+    uint32_t len = dynType_sequence_length(input);
+
+    int i = 0;
+    void *itemLoc = NULL;
+    json_t *item = NULL;
+    for (i = 0; i < len; i += 1) {
+        item = NULL;
+        status = dynType_sequence_locForIndex(type, input, i, &itemLoc);
+        if (status == OK) {
+            status = jsonSerializer_writeAny(itemType, itemLoc, &item);
+            if (status == OK) {
+                json_array_append(array, item);
+                json_decref(item);
+            }
+        }
+
+        if (status != OK) {
+            break;
+        }
+    }
+
+    if (status == OK && array != NULL) {
+        *out = array;
+    }
+
+    return status;
+}
+
+static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t **out) {
+    assert(dynType_type(type) == DYN_TYPE_COMPLEX);
+    int status = OK;
+
+    json_t *val = json_object();
+    struct complex_type_entry *entry = NULL;
+    struct complex_type_entries_head *entries = NULL;
+    int index = -1;
+
+    status = dynType_complex_entries(type, &entries);
+    if (status == OK) {
+        TAILQ_FOREACH(entry, entries, entries) {
+            void *subLoc = NULL;
+            json_t *subVal = NULL;
+            dyn_type *subType = NULL;
+            index = dynType_complex_indexForName(type, entry->name);
+            if (index < 0) {
+		LOG_ERROR("Cannot find index for member '%s'", entry->name);
+                status = ERROR;
+            }
+            if(status == OK){
+		status = dynType_complex_valLocAt(type, index, input, &subLoc);
+            }
+            if (status == OK) {
+                status = dynType_complex_dynTypeAt(type, index, &subType);
+            }
+            if (status == OK) {
+                status = jsonSerializer_writeAny(subType, subLoc, &subVal);
+            }
+            if (status == OK) {
+                json_object_set(val, entry->name, subVal);
+                json_decref(subVal);
+            }
+
+            if (status != OK) {
+                break;
+            }
+        }
+    }
+
+    if (status == OK && val != NULL) {
+        *out = val;
+    }
+
+    return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/avro_descriptor_translator_tests.cpp
----------------------------------------------------------------------
diff --git a/dfi/test/avro_descriptor_translator_tests.cpp b/dfi/test/avro_descriptor_translator_tests.cpp
new file mode 100644
index 0000000..5bab518
--- /dev/null
+++ b/dfi/test/avro_descriptor_translator_tests.cpp
@@ -0,0 +1,180 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"                                                                                                                                                                        
+
+extern "C" {
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include "dyn_common.h"
+#include "descriptor_translator.h"
+
+#if defined(BSD) || defined(__APPLE__) 
+#include "open_memstream.h"
+#include "fmemopen.h"
+#endif
+
+    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");
+        va_end(ap);
+    }
+
+
+    static char *readSchema(const char *file) {
+        size_t size = 0;
+        char *ptr = NULL;
+
+        FILE *schema = fopen(file, "r");
+        FILE *stream = open_memstream(&ptr, &size);
+
+        assert(schema != NULL);
+        assert(stream != NULL);
+
+        int c = fgetc(schema);
+        while (c != EOF ) {
+            fputc(c, stream);
+            c = fgetc(schema);
+        }
+        fclose(schema);
+        fclose(stream);
+
+        assert(ptr != NULL);
+        return ptr;
+    }
+
+    static dyn_interface_type *createInterfaceInfo(const char *schemaFile) {
+        char *schema = readSchema(schemaFile);
+        dyn_interface_type *ift= NULL;
+
+        int status = descriptorTranslator_translate(schema, &ift);
+        CHECK_EQUAL(0, status);
+
+        free(schema);
+        return ift;
+    }
+
+    static int countMethodInfos(dyn_interface_type *info) {
+        int count = 0;
+        method_info_type *mInfo = NULL;
+        TAILQ_FOREACH(mInfo, &info->methodInfos, entries) {
+            count +=1;
+        }
+        return count;
+    }
+
+    static int countTypeInfos(dyn_interface_type *info) {
+        int count = 0;
+        type_info_type *tInfo = NULL;
+        TAILQ_FOREACH(tInfo, &info->typeInfos, entries) {
+            count +=1;
+        }
+        return count;
+    }
+
+    static void simple(void) {
+        //first argument void *handle, last argument output pointer for result and return int with status for exception handling
+        //sum(DD)D -> sum(PDD*D)N 
+        //sub(DD)D -> sub(PDD*D)N
+        //sqrt(D)D -> sqrt(PD*D)N
+
+        dyn_interface_type *intf = createInterfaceInfo("schemas/simple.avpr");
+
+        int count = countMethodInfos(intf);
+        CHECK_EQUAL(3, count);
+
+        count = countTypeInfos(intf);
+        CHECK_EQUAL(0, count);
+
+        method_info_type *mInfo = NULL;
+        TAILQ_FOREACH(mInfo, &intf->methodInfos, entries) {
+            if (strcmp("sum", mInfo->name) == 0) {
+                STRCMP_EQUAL("sum(PDD*D)N", mInfo->descriptor);
+            } else if (strcmp("add", mInfo->name) == 0) {
+                STRCMP_EQUAL("add(PDD*D)N", mInfo->descriptor);
+            } else if (strcmp("sqrt", mInfo->name) == 0) {
+                STRCMP_EQUAL("sqrt(PD*D)N", mInfo->descriptor);
+            }
+        }
+
+        dynInterface_destroy(intf);
+    }
+
+    static void complex(void) {
+        dyn_interface_type *intf = createInterfaceInfo("schemas/complex.avpr");
+
+        int count = countMethodInfos(intf);
+        CHECK_EQUAL(1, count);
+
+        method_info_type *mInfo = TAILQ_FIRST(&intf->methodInfos);
+        STRCMP_EQUAL("stats", mInfo->name);
+        STRCMP_EQUAL("stats(P[D*LStatResult;)N", mInfo->descriptor);
+
+        count = countTypeInfos(intf);
+        CHECK_EQUAL(1, count);
+
+        type_info_type *tInfo = TAILQ_FIRST(&intf->typeInfos);
+        STRCMP_EQUAL("StatResult", tInfo->name);
+        STRCMP_EQUAL("{DDD[D sum min max input}", tInfo->descriptor);
+
+        dynInterface_destroy(intf);
+    }
+
+    static void invalid(const char *file) {
+        char *schema = readSchema(file);
+        dyn_interface_type *ift= NULL;
+
+        int status = descriptorTranslator_translate(schema, &ift);
+        CHECK(status != 0);
+        
+        free(schema);
+    }
+}
+
+TEST_GROUP(AvroDescTranslatorTest) {
+    void setup() {
+        descriptorTranslator_logSetup(stdLog, NULL, 3);
+        dynInterface_logSetup(stdLog, NULL, 3);
+        dynType_logSetup(stdLog, NULL, 3);
+        dynCommon_logSetup(stdLog, NULL, 3);
+    }
+};
+
+TEST(AvroDescTranslatorTest, simple) {
+    simple();
+}
+
+TEST(AvroDescTranslatorTest, complex) {
+    complex();
+}
+
+TEST(AvroDescTranslatorTest, invalid1) {
+    invalid("schemas/invalid1.avpr");
+}
+
+TEST(AvroDescTranslatorTest, invalid2) {
+    invalid("schemas/invalid2.avpr");
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/example1.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/example1.descriptor b/dfi/test/descriptors/example1.descriptor
new file mode 100644
index 0000000..771dc5e
--- /dev/null
+++ b/dfi/test/descriptors/example1.descriptor
@@ -0,0 +1,13 @@
+:header
+type=interface
+name=calculator
+version=1.0.0
+:annotations
+classname=org.example.Calculator
+:types
+StatsResult={DDD[D average min max input}
+: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
+stats([D)LStatsResult;=stats(#am=handle;P[D#am=out;*LStatsResult;)N

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/example2.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/example2.descriptor b/dfi/test/descriptors/example2.descriptor
new file mode 100644
index 0000000..38bf442
--- /dev/null
+++ b/dfi/test/descriptors/example2.descriptor
@@ -0,0 +1,9 @@
+:header
+type=interface
+name=example
+version=1.0.0
+:annotations
+:types
+item={DD a b}
+:methods
+example1=items(#am=handle;P#am=out;**[Litem;)N

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/example3.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/example3.descriptor b/dfi/test/descriptors/example3.descriptor
new file mode 100644
index 0000000..c89d969
--- /dev/null
+++ b/dfi/test/descriptors/example3.descriptor
@@ -0,0 +1,11 @@
+:header
+type=interface
+name=detection_provider
+version=1.0.0
+:annotations
+:types
+location={DD lat lon}
+target={Jllocation;DDJ id location speed heading lastUpdated}
+detection={Jllocation;Dltarget; id center range simulated}
+:methods
+getDetections()Ljava/util/List;=getDetections(#am=handle;P#am=out;**[Ldetection;)N

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/example4.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/example4.descriptor b/dfi/test/descriptors/example4.descriptor
new file mode 100644
index 0000000..4c959c4
--- /dev/null
+++ b/dfi/test/descriptors/example4.descriptor
@@ -0,0 +1,8 @@
+:header
+type=interface
+name=example4
+version=1.0.0
+:annotations
+:types
+:methods
+getName(V)t=getName(#am=handle;P#am=out;*t)N

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalid.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalid.descriptor b/dfi/test/descriptors/invalids/invalid.descriptor
new file mode 100644
index 0000000..fead964
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalid.descriptor
@@ -0,0 +1,13 @@
+:header
+type=interface
+name=calculator X
+version=1.0.0
+:annotations
+classname=org.example.Calculator
+:types
+StatsResult={DDD[D average min max input}
+: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
+stats([D)LStatsResult;=stats(#am=handle;P[D#am=out;*LStatsResult;)N

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidMetaType.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidMetaType.descriptor b/dfi/test/descriptors/invalids/invalidMetaType.descriptor
new file mode 100644
index 0000000..2d17c47
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidMetaType.descriptor
@@ -0,0 +1,8 @@
+:header
+type=interface
+name=calculator
+version=1.0.0
+:annotations
+classname=org.example.Calculator
+:methods
+add(DD)D=add(#am=invalid;PDD#am=pre;*D)N

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidMethod.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidMethod.descriptor b/dfi/test/descriptors/invalids/invalidMethod.descriptor
new file mode 100644
index 0000000..eaef7b1
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidMethod.descriptor
@@ -0,0 +1,8 @@
+:header
+type=interface
+name=calculator
+version=1.0.0
+:annotations
+classname=org.example.Calculator
+:methods
+add(DD)D=add(#am=handle;PDD#am=pre;*D)N X

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidMethodReturnType.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidMethodReturnType.descriptor b/dfi/test/descriptors/invalids/invalidMethodReturnType.descriptor
new file mode 100644
index 0000000..26f75f8
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidMethodReturnType.descriptor
@@ -0,0 +1,8 @@
+:header
+type=interface
+name=calculator
+version=1.0.0
+:annotations
+classname=org.example.Calculator
+:methods
+add(DD)D=add(#am=handle;PDD#am=pre;*D)D

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidMsgHdr.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidMsgHdr.descriptor b/dfi/test/descriptors/invalids/invalidMsgHdr.descriptor
new file mode 100644
index 0000000..ae9b131
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidMsgHdr.descriptor
@@ -0,0 +1,9 @@
+:header
+type=message
+name=poi
+:annotations
+classname=org.example.PointOfInterest
+:types
+location={DD lat long}
+:message
+{llocation;tt location name description}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidMsgInvalidName.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidMsgInvalidName.descriptor b/dfi/test/descriptors/invalids/invalidMsgInvalidName.descriptor
new file mode 100644
index 0000000..787dd4c
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidMsgInvalidName.descriptor
@@ -0,0 +1,9 @@
+:header
+type=message
+name=poi X
+:annotations
+classname=org.example.PointOfInterest
+:types
+location={DD lat long}
+:message
+{llocation;tt location name description}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidMsgInvalidSection.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidMsgInvalidSection.descriptor b/dfi/test/descriptors/invalids/invalidMsgInvalidSection.descriptor
new file mode 100644
index 0000000..02a593c
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidMsgInvalidSection.descriptor
@@ -0,0 +1,10 @@
+:header
+type=message
+name=poi
+version=1.0.0
+:invalid
+classname=org.example.PointOfInterest
+:types
+location={DD lat long}
+:message
+{llocation;tt location name description}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidMsgInvalidType.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidMsgInvalidType.descriptor b/dfi/test/descriptors/invalids/invalidMsgInvalidType.descriptor
new file mode 100644
index 0000000..5008311
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidMsgInvalidType.descriptor
@@ -0,0 +1,9 @@
+:header
+type=message
+name=poi
+:annotations
+classname=org.example.PointOfInterest
+:types
+location={DD lat long} X
+:message
+{llocation;tt location name description}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidMsgInvalidVersion.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidMsgInvalidVersion.descriptor b/dfi/test/descriptors/invalids/invalidMsgInvalidVersion.descriptor
new file mode 100644
index 0000000..6cffbdc
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidMsgInvalidVersion.descriptor
@@ -0,0 +1,10 @@
+:header
+type=message
+name=poi
+version=1.0.f
+:annotations
+classname=org.example.PointOfInterest
+:types
+location={DD lat long}
+:message
+{llocation;tt location name description}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidMsgMissingVersion.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidMsgMissingVersion.descriptor b/dfi/test/descriptors/invalids/invalidMsgMissingVersion.descriptor
new file mode 100644
index 0000000..1fd3595
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidMsgMissingVersion.descriptor
@@ -0,0 +1,10 @@
+:head
+type=message
+name=poi
+version=1.0.0
+:annotations
+classname=org.example.PointOfInterest
+:types
+location={DD lat long}
+:message
+{llocation;tt location name description}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidSection.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidSection.descriptor b/dfi/test/descriptors/invalids/invalidSection.descriptor
new file mode 100644
index 0000000..b8a11a6
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidSection.descriptor
@@ -0,0 +1,6 @@
+:header
+type=interface
+name=calculator
+version=1.0.0
+:invalidSection
+invalidKey=invalidValue
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidType.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidType.descriptor b/dfi/test/descriptors/invalids/invalidType.descriptor
new file mode 100644
index 0000000..7b7ce1c
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidType.descriptor
@@ -0,0 +1,10 @@
+:header
+type=interface
+name=calculator
+version=1.0.0
+:annotations
+classname=org.example.Calculator
+:types
+StatsResult={DDD[D average min max input} X
+:methods
+stats([D)LStatsResult;=stats(#am=handle;P[D#am=out;*LStatsResult;)N

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/invalidVersion.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/invalidVersion.descriptor b/dfi/test/descriptors/invalids/invalidVersion.descriptor
new file mode 100644
index 0000000..bfe4d38
--- /dev/null
+++ b/dfi/test/descriptors/invalids/invalidVersion.descriptor
@@ -0,0 +1,9 @@
+:header
+type=interface
+name=example
+version=q.0.0
+:annotations
+:types
+item={DD a b}
+:methods
+example1=items(#am=handle;P#am=out;**[Litem;)N

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/invalids/noVersion.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/invalids/noVersion.descriptor b/dfi/test/descriptors/invalids/noVersion.descriptor
new file mode 100644
index 0000000..731a9e6
--- /dev/null
+++ b/dfi/test/descriptors/invalids/noVersion.descriptor
@@ -0,0 +1,12 @@
+:header
+type=interface
+name=calculator
+:annotations
+classname=org.example.Calculator
+:types
+StatsResult={DDD[D average min max input}
+: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
+stats([D)LStatsResult;=stats(#am=handle;P[D#am=out;*LStatsResult;)N

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/msg_example1.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/msg_example1.descriptor b/dfi/test/descriptors/msg_example1.descriptor
new file mode 100644
index 0000000..576523a
--- /dev/null
+++ b/dfi/test/descriptors/msg_example1.descriptor
@@ -0,0 +1,10 @@
+:header
+type=message
+name=poi
+version=1.0.0
+:annotations
+classname=org.example.PointOfInterest
+:types
+location={DD lat long}
+:message
+{llocation;tt location name description}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/msg_example2.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/msg_example2.descriptor b/dfi/test/descriptors/msg_example2.descriptor
new file mode 100644
index 0000000..128049d
--- /dev/null
+++ b/dfi/test/descriptors/msg_example2.descriptor
@@ -0,0 +1,12 @@
+:header
+type=message
+name=track
+version=0.0.1
+:annotations
+classname=org.example.Track
+:types
+timestamp={SSSSSSI day month year hour minute second microseconds}
+latlonpos={DD lat lon}
+polarpos={DDD azimuth elevation range}
+:message
+{Iltimestamp;llatlonpos;lpolarpos;SS trackid lastupdate abspos relpos classification identity}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/msg_example3.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/msg_example3.descriptor b/dfi/test/descriptors/msg_example3.descriptor
new file mode 100644
index 0000000..7b69380
--- /dev/null
+++ b/dfi/test/descriptors/msg_example3.descriptor
@@ -0,0 +1,10 @@
+:header
+type=message
+name=logEntry
+version=1.0.0
+:annotations
+classname=org.example.LogEntry
+:types
+timestamp={SSSSSSI day month year hour minute second microseconds}
+:message
+{ltimestamp;St timestamp severity eventdescription}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/descriptors/msg_example4.descriptor
----------------------------------------------------------------------
diff --git a/dfi/test/descriptors/msg_example4.descriptor b/dfi/test/descriptors/msg_example4.descriptor
new file mode 100644
index 0000000..e99e443
--- /dev/null
+++ b/dfi/test/descriptors/msg_example4.descriptor
@@ -0,0 +1,10 @@
+:header
+type=message
+name=exmpl4
+version=1.1.0
+:annotations
+:types
+info={Jladditional_info; id info}
+additional_info={Jt; id descr}
+:message
+{Jlinfo; id info}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/dyn_closure_tests.cpp
----------------------------------------------------------------------
diff --git a/dfi/test/dyn_closure_tests.cpp b/dfi/test/dyn_closure_tests.cpp
new file mode 100644
index 0000000..9c1abe6
--- /dev/null
+++ b/dfi/test/dyn_closure_tests.cpp
@@ -0,0 +1,162 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"                                                                                                                                                                        
+
+extern "C" {
+    
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "dyn_common.h"
+#include "dyn_function.h"
+
+static int g_count;
+
+static void stdLog(void*, 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");
+    va_end(ap);
+}
+
+#define EXAMPLE1_DESCRIPTOR "example(III)I"
+static void example1_binding(void*, void* args[], void *out) {
+    int32_t a = *((int32_t *)args[0]);
+    int32_t b = *((int32_t *)args[1]);
+    int32_t c = *((int32_t *)args[2]);
+    int32_t *ret = (int32_t *)out;
+    *ret = a + b + c;
+    g_count += 1;
+}
+
+#define EXAMPLE2_DESCRIPTOR "example(I{DDD val1 val2 val3}I)D"
+struct example2_arg2 {
+    double val1;
+    double val2;
+    double val3;
+};
+void example2_binding(void*, void* args[], void *out) {
+    int32_t a = *((int32_t *)args[0]);
+    struct example2_arg2 b =  *((struct example2_arg2 *)args[1]);
+    int32_t c = *((int32_t *)args[2]);
+    double *ret = (double *)out;
+    *ret = a + b.val1 + b.val2 + b.val3 + c;
+    g_count += 1;
+}
+
+
+#define EXAMPLE3_DESCRIPTOR "example(III){III sum max min}"
+struct example3_ret {
+    int32_t sum;
+    int32_t max;
+    int32_t min;
+};
+
+static void example3_binding(void*, void* args[], void *out) {
+    int32_t a = *((int32_t *)args[0]);
+    int32_t b = *((int32_t *)args[1]);
+    int32_t c = *((int32_t *)args[2]);
+    struct example3_ret *result = (struct example3_ret *)calloc(1,sizeof(struct example3_ret));
+    result->sum = a + b + c;
+    result->min = a <= b ? a : b;
+    result->max = a >= b ? a : b;
+    result->min = result->min <= c ? result->min : c;
+    result->max = result->max >= c ? result->max : c;
+
+    struct example3_ret **ret = (struct example3_ret **)out;
+    (*ret) = result;
+    g_count += 1;
+}
+
+static void tests() {
+    dyn_function_type *dynFunction = NULL;
+    int rc = 0;
+
+    {
+        int32_t (*func)(int32_t a, int32_t b, int32_t c) = NULL;
+        rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, NULL, &dynFunction);
+        CHECK_EQUAL(0, rc);
+        rc = dynFunction_createClosure(dynFunction, example1_binding, NULL, (void(**)(void))&func);
+        CHECK_EQUAL(0, rc);
+        int32_t ret = func(2,3,4);
+        CHECK_EQUAL(1, g_count);
+        CHECK_EQUAL(9, ret);
+        dynFunction_destroy(dynFunction);
+    }
+
+    {
+        double (*func)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
+        double (*func2)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
+        dynFunction = NULL;
+        rc = dynFunction_parseWithStr(EXAMPLE2_DESCRIPTOR, NULL, &dynFunction);
+        CHECK_EQUAL(0, rc);
+        rc = dynFunction_createClosure(dynFunction, example2_binding, NULL, (void(**)(void))&func);
+        CHECK_EQUAL(0, rc);
+        rc = dynFunction_getFnPointer(dynFunction, (void(**)(void))&func2);
+        CHECK_EQUAL(0, rc);
+        CHECK(func == func2);
+        struct example2_arg2 b;
+        b.val1 = 1.0;
+        b.val2 = 1.5;
+        b.val3 = 2.0;
+        double ret = func(2,b,4);
+        CHECK_EQUAL(2, g_count);
+        CHECK_EQUAL(10.5, ret);
+        dynFunction_destroy(dynFunction);
+    }
+
+    {
+        struct example3_ret * (*func)(int32_t a, int32_t b, int32_t c) = NULL;
+        dynFunction = NULL;
+        rc = dynFunction_parseWithStr(EXAMPLE3_DESCRIPTOR, NULL, &dynFunction);
+        CHECK_EQUAL(0, rc);
+        rc = dynFunction_createClosure(dynFunction, example3_binding, NULL, (void(**)(void))&func);
+        CHECK_EQUAL(0, rc);
+        struct example3_ret *ret = func(2,8,4);
+        CHECK_EQUAL(3, g_count);
+        CHECK_EQUAL(14, ret->sum);
+        dynFunction_destroy(dynFunction);
+        free(ret);
+    }
+}
+
+}
+
+
+TEST_GROUP(DynClosureTests) {
+    void setup() {
+        int lvl = 1;
+        dynFunction_logSetup(stdLog, NULL, lvl);
+        dynType_logSetup(stdLog, NULL, lvl);
+        dynCommon_logSetup(stdLog, NULL, lvl);
+        g_count = 0;
+    }
+};
+
+TEST(DynClosureTests, DynCLosureTest1) {
+    //TODO split up
+    tests();
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/dyn_function_tests.cpp
----------------------------------------------------------------------
diff --git a/dfi/test/dyn_function_tests.cpp b/dfi/test/dyn_function_tests.cpp
new file mode 100644
index 0000000..58ad662
--- /dev/null
+++ b/dfi/test/dyn_function_tests.cpp
@@ -0,0 +1,274 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"                                                                                                                                                                        
+
+extern "C" {
+    #include <stdio.h>
+    #include <stdint.h>
+    #include <stdlib.h>
+    #include <string.h>
+    #include <ctype.h>
+
+
+    #include "dyn_common.h"
+    #include "dyn_function.h"
+
+    static void stdLog(void*, 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");
+        va_end(ap);
+    }
+
+    #define EXAMPLE1_DESCRIPTOR "example(III)I"
+    int32_t example1(int32_t a, int32_t b, int32_t c) {
+        CHECK_EQUAL(2, a);
+        CHECK_EQUAL(4, b);
+        CHECK_EQUAL(8, c);
+        return 1;
+    }
+
+    void test_example1(void) {
+        dyn_function_type *dynFunc = NULL;
+        int rc;
+        void (*fp)(void) = (void (*)(void)) example1;
+
+        rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, NULL, &dynFunc);
+        CHECK_EQUAL(0, rc);
+
+        int32_t a = 2;
+        int32_t b = 4;
+        int32_t c = 8;
+        void *values[3];
+        int32_t rVal = 0;
+        values[0] = &a;
+        values[1] = &b;
+        values[2] = &c;
+
+        rc = dynFunction_call(dynFunc, fp, &rVal, values);
+        CHECK_EQUAL(0, rc);
+        CHECK_EQUAL(1, rVal);
+        dynFunction_destroy(dynFunc);
+    }
+
+    #define EXAMPLE2_DESCRIPTOR "example(I{IID val1 val2 val3}D)D"
+    struct example2_arg {
+        int32_t val1;
+        int32_t val2;
+        double val3;
+    };
+
+    double example2(int32_t arg1, struct example2_arg arg2, double arg3) {
+        CHECK_EQUAL(2, arg1);
+        CHECK_EQUAL(2, arg2.val1);
+        CHECK_EQUAL(3, arg2.val2);
+        CHECK_EQUAL(4.1, arg2.val3);
+        CHECK_EQUAL(8.1, arg3);
+        return 2.2;
+    }
+
+    void test_example2(void) {
+        dyn_function_type *dynFunc = NULL;
+        int rc;
+        void (*fp)(void) = (void (*)(void)) example2;
+
+        rc = dynFunction_parseWithStr(EXAMPLE2_DESCRIPTOR, NULL, &dynFunc);
+        CHECK_EQUAL(0, rc);
+
+        int32_t arg1 = 2;
+        struct example2_arg arg2;
+        arg2.val1 = 2;
+        arg2.val2 = 3;
+        arg2.val3 = 4.1;
+        double arg3 = 8.1;
+        double returnVal = 0;
+        void *values[3];
+        values[0] = &arg1;
+        values[1] = &arg2;
+        values[2] = &arg3;
+
+        rc = dynFunction_call(dynFunc, fp, &returnVal, values);
+        CHECK_EQUAL(0, rc);
+        CHECK_EQUAL(2.2, returnVal);
+        dynFunction_destroy(dynFunc);
+    }
+
+    static void test_access_functions(void) {
+        dyn_function_type *dynFunc = NULL;
+        int rc;
+        rc = dynFunction_parseWithStr("add(D{DD a b}*D)V", NULL, &dynFunc);
+
+        CHECK_EQUAL(0, rc);
+
+        int nrOfArgs = dynFunction_nrOfArguments(dynFunc);
+        CHECK_EQUAL(3, nrOfArgs);
+
+        dyn_type *arg1 = dynFunction_argumentTypeForIndex(dynFunc, 1);
+        CHECK(arg1 != NULL);
+        CHECK_EQUAL('{', (char) dynType_descriptorType(arg1));
+
+        dyn_type *nonExist = dynFunction_argumentTypeForIndex(dynFunc, 10);
+        CHECK(nonExist == NULL);
+
+        dyn_type *returnType = dynFunction_returnType(dynFunc);
+        CHECK_EQUAL('V', (char) dynType_descriptorType(returnType));
+
+        dynFunction_destroy(dynFunc);
+    }
+
+    //example with gen pointer and output
+    #define EXAMPLE3_DESCRIPTOR "example(PD*D)N"
+
+    static int testExample3(void *ptr, double a, double *out) {
+        double *b = (double *)ptr;
+        CHECK_EQUAL(2.0, *b)
+        CHECK_EQUAL(a, 2.0);
+        *out = *b * a;
+        return 0;
+    }
+
+    static void test_example3(void) {
+        dyn_function_type *dynFunc = NULL;
+        void (*fp)(void) = (void(*)(void)) testExample3;
+        int rc;
+
+        rc = dynFunction_parseWithStr(EXAMPLE3_DESCRIPTOR, NULL, &dynFunc);
+        CHECK_EQUAL(0, rc);
+        double result = -1.0;
+        double *input = &result;
+        double a = 2.0;
+        void *ptr = &a;
+        void *args[3];
+        args[0] = &ptr;
+        args[1] = &a;
+        args[2] = &input;
+        int rVal = 0;
+        rc = dynFunction_call(dynFunc, fp, &rVal, args);
+        CHECK_EQUAL(0, rc);
+        CHECK_EQUAL(4.0, result);
+
+
+        double *inMemResult = (double *)calloc(1, sizeof(double));
+        a = 2.0;
+        ptr = &a;
+        args[0] = &ptr;
+        args[1] = &a;
+        args[2] = &inMemResult;
+        rVal = 0;
+        rc = dynFunction_call(dynFunc, fp, &rVal, args);
+        CHECK_EQUAL(0, rc);
+        CHECK_EQUAL(4.0, result);
+        free(inMemResult);
+
+        dynFunction_destroy(dynFunc);
+    }
+
+    struct tst_seq {
+        uint32_t cap;
+        uint32_t len;
+        double *buf;
+    };
+
+    #define EXAMPLE4_DESCRIPTOR "example([D)V"
+
+    static void example4Func(struct tst_seq seq) {
+        CHECK_EQUAL(4, seq.cap);
+        CHECK_EQUAL(2, seq.len);
+        CHECK_EQUAL(1.1, seq.buf[0]);
+        CHECK_EQUAL(2.2, seq.buf[1]);
+    }
+
+    static void test_example4(void) {
+        dyn_function_type *dynFunc = NULL;
+        void (*fp)(void) = (void(*)(void)) example4Func;
+        int rc;
+
+        rc = dynFunction_parseWithStr(EXAMPLE4_DESCRIPTOR, NULL, &dynFunc);
+        CHECK_EQUAL(0, rc);
+
+        double buf[4];
+        buf[0] = 1.1;
+        buf[1] = 2.2;
+        struct tst_seq seq;
+        seq.cap = 4;
+        seq.len = 2;
+        seq.buf = buf;
+
+        void *args[1];
+        args[0] = &seq;
+        rc = dynFunction_call(dynFunc, fp, NULL, args);
+        CHECK_EQUAL(0, rc);
+
+        dynFunction_destroy(dynFunc);
+    }
+
+    #define INVALID_FUNC_DESCRIPTOR "example$[D)V"//$ is an invalid symbol, missing (
+
+    static void test_invalidDynFunc(void) {
+        dyn_function_type *dynFunc = NULL;
+        int rc = dynFunction_parseWithStr(INVALID_FUNC_DESCRIPTOR, NULL, &dynFunc);
+        CHECK_EQUAL(2, rc); //Mem error
+    }
+
+    #define INVALID_FUNC_TYPE_DESCRIPTOR "example(H)A"//H and A are invalid types
+
+    static void test_invalidDynFuncType(void) {
+        dyn_function_type *dynFunc = NULL;
+        int rc = dynFunction_parseWithStr(INVALID_FUNC_TYPE_DESCRIPTOR, NULL, &dynFunc);
+        CHECK_EQUAL(3, rc); //Parse Error
+    }
+}
+
+TEST_GROUP(DynFunctionTests) {
+    void setup() {
+        int lvl = 1;
+        dynFunction_logSetup(stdLog, NULL, lvl);
+        dynType_logSetup(stdLog, NULL, lvl);
+        dynCommon_logSetup(stdLog, NULL, lvl);
+    }
+};
+
+TEST(DynFunctionTests, DynFuncTest1) {
+    test_example1();
+}
+
+TEST(DynFunctionTests, DynFuncTest2) {
+    test_example2();
+}
+
+TEST(DynFunctionTests, DynFuncAccTest) {
+    test_access_functions();
+}
+
+TEST(DynFunctionTests, DynFuncTest3) {
+    test_example3();
+}
+
+TEST(DynFunctionTests, DynFuncTest4) {
+    test_example4();
+}
+
+TEST(DynFunctionTests, InvalidDynFuncTest) {
+    test_invalidDynFunc();
+    test_invalidDynFuncType();
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/dyn_interface_tests.cpp
----------------------------------------------------------------------
diff --git a/dfi/test/dyn_interface_tests.cpp b/dfi/test/dyn_interface_tests.cpp
new file mode 100644
index 0000000..df9752f
--- /dev/null
+++ b/dfi/test/dyn_interface_tests.cpp
@@ -0,0 +1,207 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"                                                                                                                                                                        
+extern "C" {
+    
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "dyn_common.h"
+#include "dyn_interface.h"
+
+#if defined(BSD) || defined(__APPLE__) 
+#include "open_memstream.h"
+#include "fmemopen.h"
+#endif
+
+    static void stdLog(void*, 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");
+        va_end(ap);
+    }
+
+    static void checkInterfaceVersion(dyn_interface_type* dynIntf, const char* v) {
+        int status;
+
+        char *version = NULL;
+        status = dynInterface_getVersionString(dynIntf, &version);
+        CHECK_EQUAL(0, status);
+        STRCMP_EQUAL(v, version);
+        version_pt msgVersion = NULL, localMsgVersion = NULL;
+        int cmpVersion = -1;
+        version_createVersionFromString(version, &localMsgVersion);
+        status = dynInterface_getVersion(dynIntf, &msgVersion);
+        CHECK_EQUAL(0, status);
+        version_compareTo(msgVersion, localMsgVersion, &cmpVersion);
+        CHECK_EQUAL(cmpVersion, 0);
+        version_destroy(localMsgVersion);
+    }
+
+    static void test1(void) {
+        int status = 0;
+        dyn_interface_type *dynIntf = NULL;
+        FILE *desc = fopen("descriptors/example1.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        CHECK_EQUAL(0, status);
+        fclose(desc);
+
+        char *name = NULL;
+        status = dynInterface_getName(dynIntf, &name);
+        CHECK_EQUAL(0, status);
+        STRCMP_EQUAL("calculator", name);
+
+	checkInterfaceVersion(dynIntf,"1.0.0");
+
+        char *annVal = NULL;
+        status = dynInterface_getAnnotationEntry(dynIntf, "classname", &annVal);
+        CHECK_EQUAL(0, status);
+        STRCMP_EQUAL("org.example.Calculator", annVal);
+
+        char *nonExist = NULL;
+        status = dynInterface_getHeaderEntry(dynIntf, "nonExisting", &nonExist);
+        CHECK(status != 0);
+        CHECK(nonExist == NULL);
+
+        struct methods_head *list = NULL;
+        status = dynInterface_methods(dynIntf, &list);
+        CHECK(status == 0);
+        CHECK(list != NULL);
+
+        int count = dynInterface_nrOfMethods(dynIntf);
+        CHECK_EQUAL(4, count);
+
+        dynInterface_destroy(dynIntf);
+    }
+
+    static void test2(void) {
+        int status = 0;
+        dyn_interface_type *dynIntf = NULL;
+        FILE *desc = fopen("descriptors/example3.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        CHECK_EQUAL(0, status);
+        fclose(desc);
+
+        dynInterface_destroy(dynIntf);
+    }
+
+    static void testInvalid(void) {
+        int status = 0;
+
+        /* Invalid field */
+        dyn_interface_type *dynIntf = NULL;
+        FILE *desc = fopen("descriptors/invalids/invalid.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        //dynInterface_destroy(dynIntf);
+        CHECK_EQUAL(1, status); //Test fails because of a space at the end of the name
+        fclose(desc); desc=NULL;
+
+
+        /* Header without Version */
+        desc = fopen("descriptors/invalids/noVersion.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        //dynInterface_destroy(dynIntf);
+        CHECK_EQUAL(1, status); //Test fails because of missing version field in header section
+        fclose(desc); desc=NULL;
+
+        /* Invalid section */
+        desc = fopen("descriptors/invalids/invalidSection.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        //dynInterface_destroy(dynIntf);
+        CHECK_EQUAL(1, status); //Test fails because of unknown section type
+        fclose(desc); desc=NULL;
+
+        /* Invalid return type */
+        desc = fopen("descriptors/invalids/invalidMethodReturnType.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        //dynInterface_destroy(dynIntf);
+        CHECK_EQUAL(1, status); //Test fails because of invalid return type (D instead of N)
+        fclose(desc); desc=NULL;
+
+        /* Invalid  method section */
+        desc = fopen("descriptors/invalids/invalidMethod.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        //dynInterface_destroy(dynIntf);
+        CHECK_EQUAL(1, status); //Test fails because of space at the end of the method
+        fclose(desc); desc=NULL;
+
+        /* Invalid type */
+        desc = fopen("descriptors/invalids/invalidType.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        //dynInterface_destroy(dynIntf);
+        CHECK_EQUAL(1, status); //Test fails because of space at the end of the type
+        fclose(desc); desc=NULL;
+
+        /* Invalid metatype in method description */
+        desc = fopen("descriptors/invalids/invalidMetaType.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        dynInterface_destroy(dynIntf);
+        CHECK_EQUAL(0, status); //Invalid meta type doesn't generate errors, just warnings
+        fclose(desc); desc=NULL; dynIntf=NULL;
+
+        /* Invalid version section */
+        desc = fopen("descriptors/invalids/invalidVersion.descriptor", "r");
+        assert(desc != NULL);
+        status = dynInterface_parse(desc, &dynIntf);
+        //dynInterface_destroy(dynIntf);
+        CHECK_EQUAL(1, status); //Invalid meta type doesn't generate errors, just warnings
+        fclose(desc); desc=NULL;
+
+    }
+}
+
+
+TEST_GROUP(DynInterfaceTests) {
+    void setup() {
+        int level = 1;
+        dynCommon_logSetup(stdLog, NULL, level);
+        dynType_logSetup(stdLog, NULL, level);
+        dynFunction_logSetup(stdLog, NULL, level);
+        dynInterface_logSetup(stdLog, NULL, level);
+    }
+};
+
+TEST(DynInterfaceTests, test1) {
+    test1();
+}
+
+TEST(DynInterfaceTests, test2) {
+    test2();
+}
+
+TEST(DynInterfaceTests, testInvalid) {
+    testInvalid();
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/dyn_message_tests.cpp
----------------------------------------------------------------------
diff --git a/dfi/test/dyn_message_tests.cpp b/dfi/test/dyn_message_tests.cpp
new file mode 100644
index 0000000..e310537
--- /dev/null
+++ b/dfi/test/dyn_message_tests.cpp
@@ -0,0 +1,253 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+extern "C" {
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "dyn_common.h"
+#include "dyn_message.h"
+
+#if defined(BSD) || defined(__APPLE__) 
+#include "open_memstream.h"
+#include "fmemopen.h"
+#endif
+
+static void stdLog(void*, 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");
+	va_end(ap);
+}
+
+static void checkMessageVersion(dyn_message_type* dynMsg, const char* v){
+	int status = 0;
+
+	char *version = NULL;
+	status = dynMessage_getVersionString(dynMsg, &version);
+	CHECK_EQUAL(0, status);
+	STRCMP_EQUAL(v, version);
+	version_pt msgVersion = NULL, localMsgVersion = NULL;
+	int cmpVersion = -1;
+	version_createVersionFromString(version,&localMsgVersion);
+	status = dynMessage_getVersion(dynMsg,&msgVersion);
+	CHECK_EQUAL(0, status);
+	version_compareTo(msgVersion,localMsgVersion,&cmpVersion);
+	CHECK_EQUAL(cmpVersion,0);
+	version_destroy(localMsgVersion);
+
+}
+
+
+static void msg_test1(void) {
+	int status = 0;
+	dyn_message_type *dynMsg = NULL;
+	FILE *desc = fopen("descriptors/msg_example1.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK_EQUAL(0, status);
+	fclose(desc);
+
+	char *name = NULL;
+	status = dynMessage_getName(dynMsg, &name);
+	CHECK_EQUAL(0, status);
+	STRCMP_EQUAL("poi", name);
+
+	checkMessageVersion(dynMsg,"1.0.0");
+
+	char *annVal = NULL;
+	status = dynMessage_getAnnotationEntry(dynMsg, "classname", &annVal);
+	CHECK_EQUAL(0, status);
+	STRCMP_EQUAL("org.example.PointOfInterest", annVal);
+
+	char *nonExist = NULL;
+	status = dynMessage_getHeaderEntry(dynMsg, "nonExisting", &nonExist);
+	CHECK(status != 0);
+	CHECK(nonExist == NULL);
+
+	dyn_type *msgType = NULL;
+	status = dynMessage_getMessageType(dynMsg, &msgType);
+	CHECK_EQUAL(0, status);
+	CHECK(msgType != NULL);
+
+	dynMessage_destroy(dynMsg);
+}
+
+
+static void msg_test2(void) {
+	int status = 0;
+	dyn_message_type *dynMsg = NULL;
+	FILE *desc = fopen("descriptors/msg_example2.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK_EQUAL(0, status);
+	fclose(desc);
+
+	char *name = NULL;
+	status = dynMessage_getName(dynMsg, &name);
+	CHECK_EQUAL(0, status);
+	STRCMP_EQUAL("track", name);
+
+	checkMessageVersion(dynMsg,"0.0.1");
+
+	char *annVal = NULL;
+	status = dynMessage_getAnnotationEntry(dynMsg, "classname", &annVal);
+	CHECK_EQUAL(0, status);
+	STRCMP_EQUAL("org.example.Track", annVal);
+
+	char *nonExist = NULL;
+	status = dynMessage_getHeaderEntry(dynMsg, "nonExisting", &nonExist);
+	CHECK(status != 0);
+	CHECK(nonExist == NULL);
+
+	dyn_type *msgType = NULL;
+	status = dynMessage_getMessageType(dynMsg, &msgType);
+	CHECK_EQUAL(0, status);
+	CHECK(msgType != NULL);
+
+	dynMessage_destroy(dynMsg);
+}
+
+static void msg_test3(void) {
+	int status = 0;
+	dyn_message_type *dynMsg = NULL;
+	FILE *desc = fopen("descriptors/msg_example3.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK_EQUAL(0, status);
+	fclose(desc);
+
+	char *name = NULL;
+	status = dynMessage_getName(dynMsg, &name);
+	CHECK_EQUAL(0, status);
+	STRCMP_EQUAL("logEntry", name);
+
+	checkMessageVersion(dynMsg,"1.0.0");
+
+	char *annVal = NULL;
+	status = dynMessage_getAnnotationEntry(dynMsg, "classname", &annVal);
+	CHECK_EQUAL(0, status);
+	STRCMP_EQUAL("org.example.LogEntry", annVal);
+
+	char *nonExist = NULL;
+	status = dynMessage_getHeaderEntry(dynMsg, "nonExisting", &nonExist);
+	CHECK(status != 0);
+	CHECK(nonExist == NULL);
+
+	dyn_type *msgType = NULL;
+	status = dynMessage_getMessageType(dynMsg, &msgType);
+	CHECK_EQUAL(0, status);
+	CHECK(msgType != NULL);
+
+	dynMessage_destroy(dynMsg);
+}
+
+static void msg_test4(void) {
+	int status = 0;
+	dyn_message_type *dynMsg = NULL;
+	FILE *desc = fopen("descriptors/msg_example4.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK(status != 0);
+	fclose(desc);
+}
+
+static void msg_invalid(void) {
+	int status = 0;
+	dyn_message_type *dynMsg = NULL;
+	FILE *desc = fopen("descriptors/invalids/invalidMsgHdr.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK_EQUAL(1, status);
+	fclose(desc);
+
+	desc = fopen("descriptors/invalids/invalidMsgMissingVersion.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK_EQUAL(1, status);
+	fclose(desc);
+
+	desc = fopen("descriptors/invalids/invalidMsgInvalidSection.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK_EQUAL(1, status);
+	fclose(desc);
+
+	desc = fopen("descriptors/invalids/invalidMsgInvalidName.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK_EQUAL(1, status);
+	fclose(desc);
+
+	desc = fopen("descriptors/invalids/invalidMsgInvalidType.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK_EQUAL(1, status);
+	fclose(desc);
+
+	desc = fopen("descriptors/invalids/invalidMsgInvalidVersion.descriptor", "r");
+	assert(desc != NULL);
+	status = dynMessage_parse(desc, &dynMsg);
+	CHECK_EQUAL(1, status);
+	fclose(desc);
+
+}
+
+}
+
+
+TEST_GROUP(DynMessageTests) {
+	void setup() {
+		int level = 1;
+		dynCommon_logSetup(stdLog, NULL, level);
+		dynType_logSetup(stdLog, NULL, level);
+		dynMessage_logSetup(stdLog, NULL, level);
+	}
+};
+
+
+TEST(DynMessageTests, msg_test1) {
+	msg_test1();
+}
+
+TEST(DynMessageTests, msg_test2) {
+	msg_test2();
+}
+
+TEST(DynMessageTests, msg_test3) {
+	msg_test3();
+}
+
+TEST(DynMessageTests, msg_test4) {
+	msg_test4();
+}
+
+TEST(DynMessageTests, msg_invalid) {
+	msg_invalid();
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/dfi/test/dyn_type_tests.cpp
----------------------------------------------------------------------
diff --git a/dfi/test/dyn_type_tests.cpp b/dfi/test/dyn_type_tests.cpp
new file mode 100644
index 0000000..52f9537
--- /dev/null
+++ b/dfi/test/dyn_type_tests.cpp
@@ -0,0 +1,297 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"                                                                                                                                                                        
+
+extern "C" {
+    #include <stdarg.h>
+    
+    #include "dyn_common.h"
+    #include "dyn_type.h"
+
+	static void stdLog(void*, 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");
+	    va_end(ap);
+	}
+
+    static void runTest(const char *descriptorStr, const char *exName) {
+        dyn_type *type;
+        type = NULL;
+        //printf("\n-- example %s with descriptor string '%s' --\n", exName, descriptorStr);
+        int status = dynType_parseWithStr(descriptorStr, exName, NULL, &type);
+        CHECK_EQUAL(0, status);
+
+        //MEM check, to try to ensure no mem leaks/corruptions occur.
+        int i;
+        int j;
+        int nrOfBurst = 10;
+        int burst = 50;
+        void *pointers[burst];
+        for (j = 0; j < nrOfBurst; j += 1) {
+            for (i = 0; i < burst ; i +=1 ) {
+                pointers[i] = NULL;
+                dynType_alloc(type, &pointers[i]);
+            }
+            for (i = 0; i < burst ; i +=1 ) {
+                dynType_free(type, pointers[i]);
+            }
+        }
+
+        FILE *stream = fopen("/dev/null", "w");
+        dynType_print(type, stream);
+        fclose(stream);
+        dynType_destroy(type);
+        //printf("--\n\n");
+    }
+}
+
+TEST_GROUP(DynTypeTests) {
+	void setup() {
+	    dynType_logSetup(stdLog, NULL, 1);
+	}
+};
+
+#define EX1 "{BbJjIiSsDFNN arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12}"
+#define EX2 "{D{DD b_1 b_2}I a b c}"
+#define EX3 "Tsub={DD b_1 b_2};{DLsub;I a b c}"
+#define EX4 "{[I numbers}"
+#define EX5 "[[{DD{iii val3_1 val3_2 val3_3} val1 val2 val3}"
+#define EX6 "Tsample={DD vala valb};Lsample;"
+#define EX7 "Tsample={DD vala valb};[Lsample;"
+#define EX8 "[Tsample={DD a b};Lsample;"
+#define EX9 "*D"
+#define EX10 "Tsample={DD a b};******Lsample;"
+#define EX11 "Tsample=D;Lsample;"
+#define EX12 "Tnode={Lnode;Lnode; left right};{Lnode; head}" //note recursive example
+#define EX13 "Ttype={DDDDD a b c d e};{ltype;Ltype;ltype;Ltype; byVal1 byRef1 byVal2 ByRef2}" 
+#define EX14 "{DD{FF{JJ}{II*{ss}}}}"  //unnamed fields
+#define EX15 "Tsample={jDD time val1 val2};Tresult={jDlsample; time result sample};Lresult;"
+#define EX16 "Tpoi={BDD id lat lon};Lpoi;"
+
+#define CREATE_EXAMPLES_TEST(DESC) \
+    TEST(DynTypeTests, ParseTestExample ## DESC) { \
+        runTest(DESC, #DESC); \
+    }    
+
+CREATE_EXAMPLES_TEST(EX1)
+CREATE_EXAMPLES_TEST(EX2)
+CREATE_EXAMPLES_TEST(EX3)
+CREATE_EXAMPLES_TEST(EX4)
+CREATE_EXAMPLES_TEST(EX5)
+CREATE_EXAMPLES_TEST(EX6)
+CREATE_EXAMPLES_TEST(EX7)
+CREATE_EXAMPLES_TEST(EX8)
+CREATE_EXAMPLES_TEST(EX9)
+CREATE_EXAMPLES_TEST(EX10)
+CREATE_EXAMPLES_TEST(EX11)
+CREATE_EXAMPLES_TEST(EX12)
+CREATE_EXAMPLES_TEST(EX13)
+CREATE_EXAMPLES_TEST(EX14)
+CREATE_EXAMPLES_TEST(EX15)
+CREATE_EXAMPLES_TEST(EX16)
+
+TEST(DynTypeTests, ParseRandomGarbageTest) {
+    /*
+    unsigned int seed = 4148;
+    char *testRandom = getenv("DYN_TYPE_TEST_RANDOM");
+    if (testRandom != NULL && strcmp("true", testRandom) == 0) {
+        seed = (unsigned int) time(NULL);
+    } 
+    srandom(seed);
+    size_t nrOfTests = 100;
+
+    printf("\nStarting test with random seed %i and nrOfTests %zu.\n", seed, nrOfTests);
+
+    int i;
+    int k;
+    int c;
+    int sucesses = 0;
+    char descriptorStr[32];
+    descriptorStr[31] = '\0';
+    for(i = 0; i < nrOfTests; i += 1) {  
+        for(k = 0; k < 31; k += 1) {
+            do {
+                c = (char) (((random() * 128) / RAND_MAX) - 1);
+            } while (!isprint(c));
+            descriptorStr[k] = c;
+            if (c == '\0') { 
+                break;
+            }
+        }
+
+        //printf("ParseRandomGarbageTest iteration %i with descriptor string '%s'\n", k, descriptorStr); 
+        dyn_type *type = NULL;	
+        int status = dynType_parseWithStr(descriptorStr, NULL, NULL, &type);
+        if (status == 0) {
+            dynType_destroy(type);
+        }
+    }
+     */
+}
+
+TEST(DynTypeTests, AssignTest1) {
+    struct ex1 {
+        int32_t a;
+        int32_t b;
+        int32_t c;
+    };
+    struct ex1 inst;
+    const char *desc = "{III a b c}";
+    dyn_type *type = NULL;
+    int status = dynType_parseWithStr(desc, NULL, NULL, &type);
+    CHECK_EQUAL(0, status);
+    int32_t val1 = 2;
+    int32_t val2 = 4;
+    int32_t val3 = 8;
+    dynType_complex_setValueAt(type, 0,  &inst, &val1);
+    CHECK_EQUAL(2, inst.a);
+    dynType_complex_setValueAt(type, 1,  &inst, &val2);
+    CHECK_EQUAL(4, inst.b);
+    dynType_complex_setValueAt(type, 2,  &inst, &val3);
+    CHECK_EQUAL(8, inst.c);
+
+    dynType_destroy(type);
+}
+
+TEST(DynTypeTests, AssignTest2) {
+    struct ex {
+        int32_t a;
+        struct {
+            double a;
+            double b;
+        } b;
+    };
+    struct ex inst;
+    const char *desc = "{I{DD a b} a b}";
+    dyn_type *type = NULL;
+    int status = dynType_parseWithStr(desc, NULL, NULL,  &type);
+    CHECK_EQUAL(0, status);
+    int32_t a = 2;
+    double b_a = 1.1;
+    double b_b = 1.2;
+
+    dynType_complex_setValueAt(type, 0,  &inst, &a);
+    CHECK_EQUAL(2, inst.a);
+
+    void *loc = NULL;
+    dyn_type *subType = NULL;
+    dynType_complex_valLocAt(type, 1, (void *)&inst, &loc);
+    dynType_complex_dynTypeAt(type, 1, &subType);
+
+    dynType_complex_setValueAt(subType, 0, &inst.b, &b_a);
+    CHECK_EQUAL(1.1, inst.b.a);
+
+    dynType_complex_setValueAt(subType, 1, &inst.b, &b_b);
+    CHECK_EQUAL(1.2, inst.b.b);
+
+    dynType_destroy(type);
+}
+
+TEST(DynTypeTests, AssignTest3) {
+    int simple = 1;
+    dyn_type *type = NULL;
+    int rc = dynType_parseWithStr("N", NULL, NULL, &type);
+    CHECK_EQUAL(0, rc);
+
+    int newValue = 42;
+    void *loc = &simple;
+    void *input = &newValue;
+    dynType_simple_setValue(type, loc, input);
+    CHECK_EQUAL(42, simple);
+    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);
+}
+
+TEST(DynTypeTests, SequenceWithPointerTest) {
+    struct val {
+        double a;
+        double b;
+    };
+
+    struct item {
+        int64_t a;
+        const char *text;
+        struct val val;
+        double c;
+        double d;
+        long e;
+    };
+
+    struct item_sequence {
+        uint32_t cap;
+        uint32_t len;
+        struct item **buf;
+    };
+
+    dyn_type *type = NULL;
+    int rc = 0;
+    rc = dynType_parseWithStr("Tval={DD a b};Titem={Jtlval;DDJ a text val c d e};**[Litem;", NULL, NULL, &type);
+    CHECK_EQUAL(0, rc);
+
+    struct item_sequence *seq = NULL;
+    rc = dynType_alloc(type, (void **)&seq);
+    CHECK_EQUAL(0, rc);
+    CHECK(seq != NULL);
+
+    dynType_free(type, seq);
+
+    /*
+
+
+    struct item_sequence *items = (struct item_sequence *) calloc(1,sizeof(struct item_sequence));
+    items->buf = (struct item **) calloc(2, sizeof(struct item *));
+    items->cap = 2;
+    items->len = 2;
+    items->buf[0] = (struct item *)calloc(1, sizeof(struct item));
+    items->buf[0]->text = strdup("boe");
+    items->buf[1] = (struct item *)calloc(1, sizeof(struct item));
+    items->buf[1]->text = strdup("boe2");
+
+    dynType_free(type, items);
+     */
+
+    dynType_destroy(type);
+}
+