-/*\r
- Copyright (C) 2012 Modelon AB\r
-\r
- This program is free software: you can redistribute it and/or modify\r
- it under the terms of the BSD style license.\r
-\r
- This program is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- FMILIB_License.txt file for more details.\r
-\r
- You should have received a copy of the FMILIB_License.txt file\r
- along with this program. If not, contact Modelon AB <http://www.modelon.com>.\r
-*/\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdio.h>\r
-#include <FMI/fmi_util.h>\r
-#include <FMI/fmi_zip_unzip.h>\r
-\r
-char* fmi_construct_dll_dir_name(jm_callbacks* callbacks, const char* fmu_unzipped_path) {\r
- char* dir_path;\r
- size_t len;\r
-\r
- assert( fmu_unzipped_path && callbacks);\r
-\r
- len = \r
- strlen(fmu_unzipped_path) + strlen(FMI_FILE_SEP)\r
- + strlen(FMI_BINARIES) + strlen(FMI_FILE_SEP) \r
- + strlen(FMI_PLATFORM) + strlen(FMI_FILE_SEP) + 1;\r
-\r
- dir_path = (char*)callbacks->malloc(len);\r
- if (dir_path == NULL) {\r
- jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");\r
- return NULL;\r
- }\r
-\r
- sprintf(dir_path, "%s%s%s%s%s%s", fmu_unzipped_path, FMI_FILE_SEP, FMI_BINARIES, FMI_FILE_SEP, FMI_PLATFORM, FMI_FILE_SEP);/*safe */\r
-\r
- return dir_path;\r
-}\r
-\r
-char* fmi_construct_dll_file_name(jm_callbacks* callbacks, const char* dll_dir_name, const char* model_identifier) {\r
- char* fname;\r
- size_t len;\r
- assert(callbacks && model_identifier);\r
- len = \r
- strlen(dll_dir_name) +\r
- strlen(model_identifier) \r
- + strlen(FMI_DLL_EXT) + 1;\r
- fname = (char*)callbacks->malloc(len);\r
- if (fname == NULL) {\r
- jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");\r
- return NULL;\r
- }\r
- sprintf(fname, "%s%s%s", dll_dir_name, model_identifier, FMI_DLL_EXT);/*safe */\r
-\r
- return fname;\r
-}\r
-\r
-\r
-////\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <stdarg.h>\r
-#include <string.h>\r
-#include <errno.h>\r
-\r
-#include <fmilib.h>\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-typedef struct {\r
- char *name;\r
- char *description;\r
- char *declaredType;\r
- long vr;\r
- // 0 = real\r
- // 1 = integer\r
- // 2 = boolean\r
- // 3 = string\r
- // 4 = enumeration\r
- int type;\r
- // 0 = constant\r
- // 1 = parameter\r
- // 2 = discrete\r
- // 3 = continuous\r
- // 4 = unknown\r
- int variability;\r
- // 0 = input\r
- // 1 = output\r
- // 2 = internal\r
- // 3 = none\r
- // 4 = unknown\r
- int causality;\r
-} FMIL_Variable;\r
-\r
-typedef struct {\r
- char *name;\r
- char *description;\r
- char *quantity;\r
- char *unit;\r
-} FMIL_DeclaredType;\r
-\r
-__declspec(dllexport) void* FMI1_CS_LOAD(const char *zipFilePath, const char *unzipFolder);\r
-__declspec(dllexport) int FMI1_CS_UNLOAD(void* fmu);\r
-__declspec(dllexport) FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count);\r
-__declspec(dllexport) FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void* fmu, int *count);\r
-__declspec(dllexport) int FMI1_CS_INSTANTIATE(void* fmu);\r
-__declspec(dllexport) int FMI1_CS_INITIALIZE(void* fmu);\r
-__declspec(dllexport) int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize);\r
-__declspec(dllexport) int FMI1_CS_SET_REAL(void* fmu, int vr, double value);\r
-__declspec(dllexport) double FMI1_CS_GET_REAL(void* fmu, int vr);\r
-__declspec(dllexport) int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#define BUFFER 4096\r
-\r
-/* Logger function used by the C-API */\r
-void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)\r
-{\r
- printf("module = %s, log level = %d: %s\n", module, log_level, message);\r
-}\r
-\r
-/* Logger function used by the FMU internally */\r
-void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)\r
-{\r
- char msg[BUFFER];\r
- int len;\r
- va_list argp; \r
- va_start(argp, message);\r
- /*len=jm_vsnprintf(msg, BUFFER, message, argp);\r
- printf("fmiStatus = %d; %s (%s): %s\n", status, instanceName, category, msg);\r
- if(len > BUFFER) {\r
- printf("Warning: message was trancated");\r
- }*/\r
-}\r
-\r
-void *FMI1_CS_LOAD(char *zipFilePath, char *unzipFolder) {\r
-\r
- fmi1_callback_functions_t callBackFunctions;\r
- fmi_import_context_t* context;\r
- fmi1_fmu_kind_enu_t standard = fmi1_fmu_kind_enu_cs_standalone; \r
- fmi_version_enu_t version;\r
- jm_status_enu_t status;\r
- fmi1_import_t *fmu;\r
- jm_callbacks* callbacks;\r
-\r
- callbacks = (jm_callbacks *)calloc(1, sizeof(jm_callbacks));\r
-\r
- callbacks->malloc = malloc;\r
- callbacks->calloc = calloc;\r
- callbacks->realloc = realloc;\r
- callbacks->free = free;\r
- callbacks->logger = importlogger;\r
- callbacks->log_level = jm_log_level_debug;\r
- callbacks->context = 0;\r
-\r
- callBackFunctions.logger = fmilogger;\r
- callBackFunctions.allocateMemory = calloc;\r
- callBackFunctions.freeMemory = free;\r
-\r
- context = fmi_import_allocate_context(callbacks);\r
-\r
- version = fmi_import_get_fmi_version(context, zipFilePath, unzipFolder);\r
-\r
- fmu = fmi1_import_parse_xml(context, unzipFolder);\r
-\r
- status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 0);\r
-\r
- fmi_import_free_context(context);\r
-\r
- return fmu;\r
-\r
-}\r
-\r
-int FMI1_CS_UNLOAD(void *fmu_) {\r
-\r
- fmi1_import_t *fmu = (fmi1_import_t *)fmu_;\r
-\r
- fmi1_import_destroy_dllfmu(fmu);\r
-\r
- fmi1_import_free(fmu);\r
-\r
- return 1;\r
-\r
-}\r
-\r
-/*\r
- if(!vt) {\r
- printf("No type definition\n");\r
- return;\r
- }\r
-\r
- quan = fmi1_import_get_type_quantity(vt);\r
-\r
- printf("Type %s\n description: %s\n", fmi1_import_get_type_name(vt), fmi1_import_get_type_description(vt));\r
-\r
- printf("Base type: %s\n", fmi1_base_type_to_string(fmi1_import_get_base_type(vt)));\r
-\r
- if(quan) {\r
- printf("Quantity: %s\n", quan);\r
- }\r
- switch(fmi1_import_get_base_type(vt)) {\r
- case fmi1_base_type_real: {\r
- fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(vt);\r
- fmi1_real_t min = fmi1_import_get_real_type_min(rt);\r
- fmi1_real_t max = fmi1_import_get_real_type_max(rt);\r
- fmi1_real_t nom = fmi1_import_get_real_type_nominal(rt);\r
- fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);\r
- fmi1_import_display_unit_t* du = fmi1_import_get_type_display_unit(rt);\r
-\r
- printf("Min %g, max %g, nominal %g\n", min, max, nom);\r
-\r
- if(u) {\r
- printf("Unit: %s\n", fmi1_import_get_unit_name(u));\r
- }\r
- if(du) {\r
- printf("Display unit: %s, gain: %g, offset: %g, is relative: %s",\r
- fmi1_import_get_display_unit_name(du),\r
- fmi1_import_get_display_unit_gain(du),\r
- fmi1_import_get_display_unit_offset(du),\r
- fmi1_import_get_real_type_is_relative_quantity(rt)?"yes":"no"\r
- );\r
- }\r
-\r
- break;\r
- }\r
- case fmi1_base_type_int:{\r
- fmi1_import_integer_typedef_t* it = fmi1_import_get_type_as_int(vt);\r
- int min = fmi1_import_get_integer_type_min(it);\r
- int max = fmi1_import_get_integer_type_max(it);\r
- printf("Min %d, max %d\n", min, max);\r
- break;\r
- }\r
- case fmi1_base_type_bool:{\r
- break;\r
- }\r
- case fmi1_base_type_str:{\r
- break;\r
- }\r
- case fmi1_base_type_enum:{\r
- fmi1_import_enumeration_typedef_t* et = fmi1_import_get_type_as_enum(vt);\r
- int min = fmi1_import_get_enum_type_min(et);\r
- int max = fmi1_import_get_enum_type_max(et);\r
- printf("Min %d, max %d\n", min, max);\r
- {\r
- size_t ni;\r
- unsigned i;\r
- ni = fmi1_import_get_enum_type_size(et);\r
- i = (unsigned)(ni);\r
- assert( i == ni);\r
- printf("There are %u items \n",(unsigned)ni);\r
- for(i = 0; i < ni; i++) {\r
- printf("[%u] %s (%s) \n", (unsigned)i+1, fmi1_import_get_enum_type_item_name(et, i), fmi1_import_get_enum_type_item_description(et, i));\r
- }\r
- }\r
- break;\r
- }\r
- default:\r
- printf("Error in fmiGetBaseType()\n");\r
- }\r
-*/\r
-\r
-\r
-FMIL_Variable *FMI1_CS_GET_VARIABLES(void *fmu, int *count) {\r
-\r
- int i;\r
- FMIL_Variable *result;\r
- fmi1_import_variable_list_t* vl = fmi1_import_get_variable_list((fmi1_import_t *)fmu);\r
- fmi1_import_variable_typedef_t* type;\r
-\r
- count[0] = fmi1_import_get_variable_list_size(vl);\r
-\r
- result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));\r
-\r
- for(i = 0; i < count[0]; i++) {\r
-\r
- fmi1_import_variable_t* var = fmi1_import_get_variable(vl, i);\r
- if(!var) {\r
-\r
- printf("Something wrong with variable %d \n",i);\r
- return 0;\r
-\r
- } else {\r
-\r
- result[i].name = fmi1_import_get_variable_name(var);\r
- result[i].description = fmi1_import_get_variable_description(var);\r
-\r
- switch (fmi1_import_get_variability(var)) {\r
- case fmi1_variability_enu_constant:\r
- result[i].variability = 0;\r
- break;\r
- case fmi1_variability_enu_parameter:\r
- result[i].variability = 1;\r
- break;\r
- case fmi1_variability_enu_discrete:\r
- result[i].variability = 2;\r
- break;\r
- case fmi1_variability_enu_continuous:\r
- result[i].variability = 3;\r
- break;\r
- case fmi1_variability_enu_unknown:\r
- result[i].variability = 4;\r
- break;\r
- }\r
-\r
- switch (fmi1_import_get_causality(var)) {\r
- case fmi1_causality_enu_input:\r
- result[i].causality = 0;\r
- break;\r
- case fmi1_causality_enu_output:\r
- result[i].causality = 1;\r
- break;\r
- case fmi1_causality_enu_internal:\r
- result[i].causality = 2;\r
- break;\r
- case fmi1_causality_enu_none:\r
- result[i].causality = 3;\r
- break;\r
- case fmi1_causality_enu_unknown:\r
- result[i].causality = 4;\r
- break;\r
- }\r
-\r
- switch (fmi1_import_get_variable_base_type(var)) {\r
- case fmi1_base_type_real:\r
- result[i].type = 0;\r
- break;\r
- case fmi1_base_type_int:\r
- result[i].type = 1;\r
- break;\r
- case fmi1_base_type_bool:\r
- result[i].type = 2;\r
- break;\r
- case fmi1_base_type_str:\r
- result[i].type = 3;\r
- break;\r
- case fmi1_base_type_enum:\r
- result[i].type = 4;\r
- break;\r
- }\r
- \r
- result[i].vr = fmi1_import_get_variable_vr(var);\r
-\r
- type = fmi1_import_get_variable_declared_type(var);\r
- if(type) {\r
- result[i].declaredType = fmi1_import_get_type_name(type);\r
- } else {\r
- result[i].declaredType = 0;\r
- }\r
-\r
- }\r
-\r
- }\r
-\r
- fmi1_import_free_variable_list(vl);\r
-\r
- return result;\r
-\r
-}\r
-\r
-FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void *fmu, int *count) {\r
-\r
- FMIL_DeclaredType *result;\r
- fmi1_import_type_definitions_t* td = fmi1_import_get_type_definitions((fmi1_import_t *)fmu);\r
- fmi1_import_variable_typedef_t* type;\r
- unsigned i, ntd = (unsigned)fmi1_import_get_type_definition_number(td);\r
-\r
- count[0] = ntd;\r
-\r
- result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));\r
-\r
- for(i = 0; i < ntd; i++) {\r
- type = fmi1_import_get_typedef(td, i);\r
- result[i].name = fmi1_import_get_type_name(type);\r
- result[i].description = fmi1_import_get_type_description(type);\r
- result[i].quantity = fmi1_import_get_type_quantity(type);\r
- result[i].unit = 0;\r
-\r
- switch(fmi1_import_get_base_type(type)) {\r
- case fmi1_base_type_real: {\r
- fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(type);\r
- fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);\r
- if(u) result[i].unit = fmi1_import_get_unit_name(u);\r
- }\r
- }\r
-\r
- }\r
-\r
- return result;\r
-\r
-}\r
-\r
-#define INSTANCE_NAME "kekkeli"\r
-\r
-int FMI1_CS_INSTANTIATE(void *fmu) {\r
-\r
- fmi1_string_t fmuLocation;\r
- fmi1_string_t mimeType;\r
- fmi1_real_t timeout;\r
- fmi1_boolean_t visible;\r
- fmi1_boolean_t interactive;\r
- fmi1_boolean_t loggingOn;\r
-\r
- fmuLocation = "";\r
- mimeType = "";\r
- timeout = 0;\r
- visible = fmi1_false;\r
- interactive = fmi1_false;\r
- loggingOn = fmi1_true;\r
-\r
- if (fmi1_import_instantiate_slave(fmu, INSTANCE_NAME, NULL, NULL, timeout, fmi1_false, fmi1_false) == NULL) { \r
- printf("fmi1_capi_instantiate_slave: Failed\n");\r
- return 0;\r
- } else {\r
- printf("fmi1_capi_instantiate_slave: Success\n");\r
- }\r
- return 0;\r
-\r
-}\r
-\r
-int FMI1_CS_INITIALIZE(void *fmu) {\r
-\r
- fmi1_status_t status;\r
- fmi1_real_t tStart;\r
- fmi1_real_t tStop;\r
- fmi1_boolean_t StopTimeDefined;\r
-\r
- tStart = 0;\r
- tStop = 10;\r
- StopTimeDefined = fmi1_false;\r
-\r
- status = fmi1_import_initialize_slave((fmi1_import_t *)fmu, tStart, StopTimeDefined, tStop);\r
- if (status == fmi1_status_error || status == fmi1_status_fatal) {\r
- printf("fmi1_capi_initialize_slave: Failed\n");\r
- return 0;\r
- } else {\r
- printf("fmi1_capi_initialize_slave: Success\n");\r
- }\r
- return 0;\r
-\r
-}\r
-\r
-int FMI1_CS_STEP(void *fmu, double masterTime, double stepSize) {\r
-\r
- fmi1_status_t status;\r
-\r
- status = fmi1_import_do_step((fmi1_import_t *)fmu, (fmi1_real_t)masterTime, (fmi1_real_t)stepSize, fmi1_true);\r
- if (status == fmi1_status_error || status == fmi1_status_fatal) {\r
- return 1;\r
- } else {\r
- return 0;\r
- }\r
-}\r
-\r
-int FMI1_CS_SET_REAL(void *fmu, long valueId, double value) {\r
-\r
- fmi1_value_reference_t vr = valueId;\r
- fmi1_import_set_real((fmi1_import_t *)fmu, &vr, 1, &value);\r
-\r
- return 0;\r
-\r
-}\r
-\r
-double FMI1_CS_GET_REAL(void *fmu, int valueReference) {\r
-\r
- fmi1_value_reference_t vr = valueReference;\r
- fmi1_real_t value;\r
- fmi1_import_get_real((fmi1_import_t *)fmu, &vr, 1, &value);\r
- return value;\r
-\r
-}\r
-\r
-int FMI1_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count) {\r
-\r
- fmi1_value_reference_t *vrs = valueReferences;\r
- fmi1_real_t value;\r
- fmi1_import_get_real((fmi1_import_t *)fmu, vrs, count, result);\r
- return 1;\r
-\r
-}\r
+/*
+ Copyright (C) 2012 Modelon AB
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the BSD style license.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ FMILIB_License.txt file for more details.
+
+ You should have received a copy of the FMILIB_License.txt file
+ along with this program. If not, contact Modelon AB <http://www.modelon.com>.
+*/
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <FMI/fmi_util.h>
+#include <FMI/fmi_zip_unzip.h>
+
+char* fmi_construct_dll_dir_name(jm_callbacks* callbacks, const char* fmu_unzipped_path) {
+ char* dir_path;
+ size_t len;
+
+ assert( fmu_unzipped_path && callbacks);
+
+ len =
+ strlen(fmu_unzipped_path) + strlen(FMI_FILE_SEP)
+ + strlen(FMI_BINARIES) + strlen(FMI_FILE_SEP)
+ + strlen(FMI_PLATFORM) + strlen(FMI_FILE_SEP) + 1;
+
+ dir_path = (char*)callbacks->malloc(len);
+ if (dir_path == NULL) {
+ jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
+ return NULL;
+ }
+
+ sprintf(dir_path, "%s%s%s%s%s%s", fmu_unzipped_path, FMI_FILE_SEP, FMI_BINARIES, FMI_FILE_SEP, FMI_PLATFORM, FMI_FILE_SEP);/*safe */
+
+ return dir_path;
+}
+
+char* fmi_construct_dll_file_name(jm_callbacks* callbacks, const char* dll_dir_name, const char* model_identifier) {
+ char* fname;
+ size_t len;
+ assert(callbacks && model_identifier);
+ len =
+ strlen(dll_dir_name) +
+ strlen(model_identifier)
+ + strlen(FMI_DLL_EXT) + 1;
+ fname = (char*)callbacks->malloc(len);
+ if (fname == NULL) {
+ jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
+ return NULL;
+ }
+ sprintf(fname, "%s%s%s", dll_dir_name, model_identifier, FMI_DLL_EXT);/*safe */
+
+ return fname;
+}
+
+////
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include <fmilib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ char *name;
+ char *description;
+ char *declaredType;
+ long vr;
+ // 0 = real
+ // 1 = integer
+ // 2 = boolean
+ // 3 = string
+ // 4 = enumeration
+ int type;
+ // 0 = constant
+ // 1 = parameter
+ // 2 = discrete
+ // 3 = continuous
+ // 4 = unknown
+ int variability;
+ // 0 = input
+ // 1 = output
+ // 2 = internal
+ // 3 = none
+ // 4 = unknown
+ int causality;
+} FMIL_Variable;
+
+typedef struct {
+ char *name;
+ char *description;
+ char *quantity;
+ char *unit;
+} FMIL_DeclaredType;
+
+__declspec(dllexport) int FMI_CS_LOAD(const char *zipFilePath, const char *unzipFolder, void **fmuPointer, int *fmuVersion, const char **error);
+
+__declspec(dllexport) int FMI1_CS_UNLOAD(void* fmu, const char **error);
+__declspec(dllexport) FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
+__declspec(dllexport) FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
+__declspec(dllexport) int FMI1_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
+__declspec(dllexport) int FMI1_CS_INITIALIZE(void* fmu, const char **error);
+__declspec(dllexport) int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
+__declspec(dllexport) int FMI1_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
+__declspec(dllexport) double FMI1_CS_GET_REAL(void* fmu, int vr, const char **error);
+__declspec(dllexport) int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
+
+__declspec(dllexport) int FMI2_CS_UNLOAD(void* fmu, const char **error);
+__declspec(dllexport) FMIL_Variable *FMI2_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
+__declspec(dllexport) FMIL_DeclaredType *FMI2_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
+__declspec(dllexport) int FMI2_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
+__declspec(dllexport) int FMI2_CS_INITIALIZE(void* fmu, const char **error);
+__declspec(dllexport) int FMI2_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
+__declspec(dllexport) int FMI2_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
+__declspec(dllexport) double FMI2_CS_GET_REAL(void* fmu, int vr, const char **error);
+__declspec(dllexport) int FMI2_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#define BUFFER 4096
+
+/* Logger function used by the C-API */
+void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
+{
+ printf("module = %s, log level = %d: %s\n", module, log_level, message);
+}
+
+/* Logger function used by the FMU internally */
+void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)
+{
+ char msg[BUFFER];
+ int len;
+ va_list argp;
+ va_start(argp, message);
+ /*len=jm_vsnprintf(msg, BUFFER, message, argp);
+ printf("fmiStatus = %d; %s (%s): %s\n", status, instanceName, category, msg);
+ if(len > BUFFER) {
+ printf("Warning: message was trancated");
+ }*/
+}
+
+int FMI_CS_LOAD(char *zipFilePath, char *unzipFolder, void **fmuPointer, int *fmuVersion, const char **error) {
+
+ fmi1_callback_functions_t callBackFunctions;
+ fmi2_callback_functions_t callBackFunctions2;
+ fmi_import_context_t* context;
+ fmi_version_enu_t version;
+ jm_status_enu_t status;
+ fmi1_import_t *fmu;
+ fmi2_import_t *fmu2;
+ jm_callbacks* callbacks;
+
+ callbacks = (jm_callbacks *)calloc(1, sizeof(jm_callbacks));
+
+ callbacks->malloc = malloc;
+ callbacks->calloc = calloc;
+ callbacks->realloc = realloc;
+ callbacks->free = free;
+ callbacks->logger = importlogger;
+ callbacks->log_level = jm_log_level_debug;
+ callbacks->context = 0;
+
+ context = fmi_import_allocate_context(callbacks);
+
+ version = fmi_import_get_fmi_version(context, zipFilePath, unzipFolder);
+
+ if (version == fmi_version_1_enu ) {
+ fmu = fmi1_import_parse_xml(context, unzipFolder);
+ if (fmi1_import_get_fmu_kind(fmu) != fmi1_fmu_kind_enu_cs_standalone && fmi1_import_get_fmu_kind(fmu) != fmi1_fmu_kind_enu_cs_tool) {
+ *error = "Provided FMU is version 1 but wrong type me (Model Exchange) when it should be cs (Co-Simulation)";
+ return 2; // wrong type, should be co-simulation
+ }
+
+ callBackFunctions.logger = fmilogger;
+ callBackFunctions.allocateMemory = calloc;
+ callBackFunctions.freeMemory = free;
+
+ status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 0);
+ if (status == jm_status_error) {
+ *error = fmi1_import_get_last_error(fmu);
+ return 3;
+ }
+
+ *fmuPointer = fmu;
+ *fmuVersion = 1;
+ } else if (version == fmi_version_2_0_enu) {
+ fmu2 = fmi2_import_parse_xml(context, unzipFolder, 0);
+
+ if (fmi2_import_get_fmu_kind(fmu2) != fmi1_fmu_kind_enu_cs_standalone && fmi2_import_get_fmu_kind(fmu2) != fmi1_fmu_kind_enu_cs_tool) {
+ *error = "Provided FMU is version 2.0 but wrong type me (Model Exchange) when it should be cs (Co-Simulation)";
+ return 2; // wrong type, should be co-simulation
+ }
+
+ callBackFunctions2.logger = fmi2_log_forwarding;
+ callBackFunctions2.allocateMemory = calloc;
+ callBackFunctions2.freeMemory = free;
+ callBackFunctions2.componentEnvironment = fmu2;
+
+ status = fmi2_import_create_dllfmu(fmu2, fmi2_fmu_kind_cs, &callBackFunctions2);
+ if (status == jm_status_error) {
+ *error = fmi2_import_get_last_error(fmu2);
+ return 3;
+ }
+
+ *fmuPointer = fmu2;
+ *fmuVersion = 2;
+ }
+
+ fmi_import_free_context(context);
+
+ return 0; // success
+}
+
+int FMI1_CS_UNLOAD(void *fmu_, const char **error) {
+ fmi1_import_t *fmu = (fmi1_import_t *)fmu_;
+ fmi1_import_destroy_dllfmu(fmu);
+ fmi1_import_free(fmu);
+ return 0;
+}
+
+int FMI2_CS_UNLOAD(void *fmu_, const char **error) {
+ fmi2_import_t *fmu = (fmi2_import_t *)fmu_;
+ fmi2_import_destroy_dllfmu(fmu);
+ fmi2_import_free(fmu);
+ return 0;
+}
+
+/*
+ if(!vt) {
+ printf("No type definition\n");
+ return;
+ }
+
+ quan = fmi1_import_get_type_quantity(vt);
+
+ printf("Type %s\n description: %s\n", fmi1_import_get_type_name(vt), fmi1_import_get_type_description(vt));
+
+ printf("Base type: %s\n", fmi1_base_type_to_string(fmi1_import_get_base_type(vt)));
+
+ if(quan) {
+ printf("Quantity: %s\n", quan);
+ }
+ switch(fmi1_import_get_base_type(vt)) {
+ case fmi1_base_type_real: {
+ fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(vt);
+ fmi1_real_t min = fmi1_import_get_real_type_min(rt);
+ fmi1_real_t max = fmi1_import_get_real_type_max(rt);
+ fmi1_real_t nom = fmi1_import_get_real_type_nominal(rt);
+ fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);
+ fmi1_import_display_unit_t* du = fmi1_import_get_type_display_unit(rt);
+
+ printf("Min %g, max %g, nominal %g\n", min, max, nom);
+
+ if(u) {
+ printf("Unit: %s\n", fmi1_import_get_unit_name(u));
+ }
+ if(du) {
+ printf("Display unit: %s, gain: %g, offset: %g, is relative: %s",
+ fmi1_import_get_display_unit_name(du),
+ fmi1_import_get_display_unit_gain(du),
+ fmi1_import_get_display_unit_offset(du),
+ fmi1_import_get_real_type_is_relative_quantity(rt)?"yes":"no"
+ );
+ }
+
+ break;
+ }
+ case fmi1_base_type_int:{
+ fmi1_import_integer_typedef_t* it = fmi1_import_get_type_as_int(vt);
+ int min = fmi1_import_get_integer_type_min(it);
+ int max = fmi1_import_get_integer_type_max(it);
+ printf("Min %d, max %d\n", min, max);
+ break;
+ }
+ case fmi1_base_type_bool:{
+ break;
+ }
+ case fmi1_base_type_str:{
+ break;
+ }
+ case fmi1_base_type_enum:{
+ fmi1_import_enumeration_typedef_t* et = fmi1_import_get_type_as_enum(vt);
+ int min = fmi1_import_get_enum_type_min(et);
+ int max = fmi1_import_get_enum_type_max(et);
+ printf("Min %d, max %d\n", min, max);
+ {
+ size_t ni;
+ unsigned i;
+ ni = fmi1_import_get_enum_type_size(et);
+ i = (unsigned)(ni);
+ assert( i == ni);
+ printf("There are %u items \n",(unsigned)ni);
+ for(i = 0; i < ni; i++) {
+ printf("[%u] %s (%s) \n", (unsigned)i+1, fmi1_import_get_enum_type_item_name(et, i), fmi1_import_get_enum_type_item_description(et, i));
+ }
+ }
+ break;
+ }
+ default:
+ printf("Error in fmiGetBaseType()\n");
+ }
+*/
+
+
+FMIL_Variable *FMI1_CS_GET_VARIABLES(void *fmu, int *count, const char **error) {
+
+ int i;
+ FMIL_Variable *result;
+ fmi1_import_variable_list_t* vl = fmi1_import_get_variable_list((fmi1_import_t *)fmu);
+ fmi1_import_variable_typedef_t* type;
+
+ count[0] = fmi1_import_get_variable_list_size(vl);
+
+ result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));
+
+ for(i = 0; i < count[0]; i++) {
+
+ fmi1_import_variable_t* var = fmi1_import_get_variable(vl, i);
+ if(!var) {
+
+ printf("Something wrong with variable %d \n",i);
+ return 0;
+
+ } else {
+
+ result[i].name = fmi1_import_get_variable_name(var);
+ result[i].description = fmi1_import_get_variable_description(var);
+
+ switch (fmi1_import_get_variability(var)) {
+ case fmi1_variability_enu_constant:
+ result[i].variability = 0;
+ break;
+ case fmi1_variability_enu_parameter:
+ result[i].variability = 1;
+ break;
+ case fmi1_variability_enu_discrete:
+ result[i].variability = 2;
+ break;
+ case fmi1_variability_enu_continuous:
+ result[i].variability = 3;
+ break;
+ case fmi1_variability_enu_unknown:
+ result[i].variability = 4;
+ break;
+ }
+
+ switch (fmi1_import_get_causality(var)) {
+ case fmi1_causality_enu_input:
+ result[i].causality = 0;
+ break;
+ case fmi1_causality_enu_output:
+ result[i].causality = 1;
+ break;
+ case fmi1_causality_enu_internal:
+ result[i].causality = 2;
+ break;
+ case fmi1_causality_enu_none:
+ result[i].causality = 3;
+ break;
+ case fmi1_causality_enu_unknown:
+ result[i].causality = 4;
+ break;
+ }
+
+ switch (fmi1_import_get_variable_base_type(var)) {
+ case fmi1_base_type_real:
+ result[i].type = 0;
+ break;
+ case fmi1_base_type_int:
+ result[i].type = 1;
+ break;
+ case fmi1_base_type_bool:
+ result[i].type = 2;
+ break;
+ case fmi1_base_type_str:
+ result[i].type = 3;
+ break;
+ case fmi1_base_type_enum:
+ result[i].type = 4;
+ break;
+ }
+
+ result[i].vr = fmi1_import_get_variable_vr(var);
+
+ type = fmi1_import_get_variable_declared_type(var);
+ if(type) {
+ result[i].declaredType = fmi1_import_get_type_name(type);
+ } else {
+ result[i].declaredType = 0;
+ }
+
+ }
+
+ }
+
+ fmi1_import_free_variable_list(vl);
+
+ return result;
+
+}
+
+FMIL_Variable *FMI2_CS_GET_VARIABLES(void *fmu, int *count, const char **error) {
+
+ int i;
+ FMIL_Variable *result;
+ fmi2_import_variable_list_t* vl = fmi2_import_get_variable_list((fmi2_import_t *)fmu, 0);
+ fmi2_import_variable_typedef_t* type;
+
+ count[0] = fmi2_import_get_variable_list_size(vl);
+
+ result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));
+
+ for(i = 0; i < count[0]; i++) {
+
+ fmi2_import_variable_t* var = fmi2_import_get_variable(vl, i);
+ if(!var) {
+
+ printf("Something wrong with variable %d \n",i);
+ return 0;
+
+ } else {
+
+ result[i].name = fmi2_import_get_variable_name(var);
+ result[i].description = fmi2_import_get_variable_description(var);
+
+ switch (fmi2_import_get_variability(var)) {
+ case fmi2_variability_enu_constant:
+ result[i].variability = 0;
+ break;
+ case fmi2_variability_enu_fixed:
+ case fmi2_variability_enu_tunable:
+ result[i].variability = 1;
+ break;
+ case fmi2_variability_enu_discrete:
+ result[i].variability = 2;
+ break;
+ case fmi2_variability_enu_continuous:
+ result[i].variability = 3;
+ break;
+ case fmi2_variability_enu_unknown:
+ result[i].variability = 4;
+ break;
+ }
+
+ switch (fmi2_import_get_causality(var)) {
+ case fmi2_causality_enu_input:
+ result[i].causality = 0;
+ break;
+ case fmi2_causality_enu_output:
+ result[i].causality = 1;
+ break;
+ case fmi2_causality_enu_local:
+ result[i].causality = 2;
+ break;
+ case fmi2_causality_enu_independent:
+ result[i].causality = 3;
+ break;
+ case fmi2_causality_enu_unknown:
+ result[i].causality = 4;
+ break;
+ }
+
+ switch (fmi2_import_get_variable_base_type(var)) {
+ case fmi2_base_type_real:
+ result[i].type = 0;
+ break;
+ case fmi2_base_type_int:
+ result[i].type = 1;
+ break;
+ case fmi2_base_type_bool:
+ result[i].type = 2;
+ break;
+ case fmi2_base_type_str:
+ result[i].type = 3;
+ break;
+ case fmi2_base_type_enum:
+ result[i].type = 4;
+ break;
+ }
+
+ result[i].vr = fmi2_import_get_variable_vr(var);
+
+ type = fmi2_import_get_variable_declared_type(var);
+ if(type) {
+ result[i].declaredType = fmi2_import_get_type_name(type);
+ } else {
+ result[i].declaredType = 0;
+ }
+
+ }
+
+ }
+
+ fmi2_import_free_variable_list(vl);
+
+ return result;
+
+}
+
+FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void *fmu, int *count, const char **error) {
+
+ FMIL_DeclaredType *result;
+ fmi1_import_type_definitions_t* td = fmi1_import_get_type_definitions((fmi1_import_t *)fmu);
+ fmi1_import_variable_typedef_t* type;
+ unsigned i, ntd = (unsigned)fmi1_import_get_type_definition_number(td);
+
+ count[0] = ntd;
+
+ result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));
+
+ for(i = 0; i < ntd; i++) {
+ type = fmi1_import_get_typedef(td, i);
+ result[i].name = fmi1_import_get_type_name(type);
+ result[i].description = fmi1_import_get_type_description(type);
+ result[i].quantity = fmi1_import_get_type_quantity(type);
+ result[i].unit = 0;
+
+ switch(fmi1_import_get_base_type(type)) {
+ case fmi1_base_type_real: {
+ fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(type);
+ fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);
+ if(u) result[i].unit = fmi1_import_get_unit_name(u);
+ }
+ }
+
+ }
+
+ return result;
+
+}
+
+FMIL_DeclaredType *FMI2_CS_GET_DECLARED_TYPES(void *fmu, int *count, const char **error) {
+
+ FMIL_DeclaredType *result;
+ fmi2_import_type_definitions_t* td = fmi2_import_get_type_definitions((fmi2_import_t *)fmu);
+ fmi2_import_variable_typedef_t* type;
+ unsigned i, ntd = (unsigned)fmi2_import_get_type_definition_number(td);
+
+ count[0] = ntd;
+
+ result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));
+
+ for(i = 0; i < ntd; i++) {
+ type = fmi2_import_get_typedef(td, i);
+ result[i].name = fmi2_import_get_type_name(type);
+ result[i].description = fmi2_import_get_type_description(type);
+ result[i].quantity = fmi2_import_get_type_quantity(type);
+ result[i].unit = 0;
+
+ switch(fmi2_import_get_base_type(type)) {
+ case fmi2_base_type_real: {
+ fmi2_import_real_typedef_t* rt = fmi2_import_get_type_as_real(type);
+ fmi2_import_unit_t* u = fmi2_import_get_real_type_unit(rt);
+ if(u) result[i].unit = fmi2_import_get_unit_name(u);
+ }
+ }
+
+ }
+
+ return result;
+
+}
+
+int FMI1_CS_INSTANTIATE(void *fmu, const char *instanceName, const char **error) {
+
+ fmi1_string_t fmuLocation;
+ fmi1_string_t mimeType;
+ fmi1_real_t timeout;
+ fmi1_boolean_t visible;
+ fmi1_boolean_t interactive;
+ fmi1_boolean_t loggingOn;
+
+ jm_status_enu_t jmstatus;
+
+ fmuLocation = "";
+ mimeType = "";
+ timeout = 0;
+ visible = fmi1_false;
+ interactive = fmi1_false;
+ loggingOn = fmi1_true;
+
+ jmstatus = fmi1_import_instantiate_slave((fmi1_import_t*)fmu, instanceName, NULL, NULL, timeout, fmi1_false, fmi1_false);
+ if (jmstatus == jm_status_error) {
+ *error = fmi1_import_get_last_error((fmi1_import_t*)fmu);
+ return 1;
+ }
+ return 0;
+}
+
+int FMI2_CS_INSTANTIATE(void *fmu, const char *instanceName, const char **error) {
+
+ fmi2_string_t fmuLocation;
+ fmi2_string_t mimeType;
+ fmi2_real_t timeout;
+ fmi2_boolean_t visible;
+ fmi2_boolean_t interactive;
+ fmi2_boolean_t loggingOn;
+ jm_status_enu_t jmstatus;
+
+ fmuLocation = "";
+ mimeType = "";
+ timeout = 0;
+ visible = fmi2_false;
+ jmstatus = fmi2_import_instantiate((fmi2_import_t*)fmu, instanceName, fmi2_cosimulation, NULL, visible);
+ if (jmstatus == jm_status_error) {
+ *error = fmi2_import_get_last_error((fmi2_import_t*)fmu);
+ return 1;
+ }
+ return 0;
+}
+
+int FMI1_CS_INITIALIZE(void *fmu, const char **error) {
+
+ fmi1_status_t status;
+ fmi1_real_t tStart;
+ fmi1_real_t tStop;
+ fmi1_boolean_t StopTimeDefined;
+
+ tStart = 0;
+ tStop = 10;
+ StopTimeDefined = fmi1_false;
+
+ status = fmi1_import_initialize_slave((fmi1_import_t *)fmu, tStart, StopTimeDefined, tStop);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ printf("fmi1_capi_initialize_slave: Failed\n");
+ return 0;
+ } else {
+ printf("fmi1_capi_initialize_slave: Success\n");
+ }
+ return 0;
+
+}
+
+int FMI2_CS_INITIALIZE(void *fmu, const char **error) {
+
+ fmi2_real_t tStart;
+ fmi2_real_t tStop;
+ fmi2_boolean_t StopTimeDefined;
+ fmi2_real_t relativeTol = 1e-4;
+
+ fmi2_status_t fmistatus;
+
+ tStart = 0;
+ tStop = 10;
+ StopTimeDefined = fmi1_false;
+
+ fmistatus = fmi2_import_setup_experiment((fmi2_import_t*)fmu, fmi2_true, relativeTol, tStart, StopTimeDefined, tStop);
+ if(fmistatus != fmi2_status_ok) {
+ *error = ("fmi2_import_setup_experiment failed\n");
+ return 1;
+ }
+
+ fmistatus = fmi2_import_enter_initialization_mode((fmi2_import_t*)fmu);
+ if(fmistatus != fmi2_status_ok) {
+ *error = ("fmi2_import_enter_initialization_mode failed\n");
+ return 1;
+ }
+
+ fmistatus = fmi2_import_exit_initialization_mode((fmi2_import_t*)fmu);
+ if(fmistatus != fmi2_status_ok) {
+ *error = ("fmi2_import_exit_initialization_mode failed\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+int FMI1_CS_STEP(void *fmu, double masterTime, double stepSize, const char **error) {
+
+ fmi1_status_t status;
+
+ status = fmi1_import_do_step((fmi1_import_t *)fmu, (fmi1_real_t)masterTime, (fmi1_real_t)stepSize, fmi1_true);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ *error = "Error happened during stepping!";
+ return 1;
+ }
+ return 0;
+}
+
+int FMI2_CS_STEP(void *fmu, double masterTime, double stepSize, const char **error) {
+
+ fmi2_status_t status;
+
+ status = fmi2_import_do_step((fmi2_import_t *)fmu, (fmi2_real_t)masterTime, (fmi2_real_t)stepSize, fmi2_true);
+ if (status == fmi2_status_error || status == fmi2_status_fatal) {
+ *error = "Error happened during stepping!";
+ return 1;
+ }
+ return 0;
+}
+
+int FMI1_CS_SET_REAL(void *fmu, long valueId, double value, const char **error) {
+
+ fmi1_status_t status;
+
+ fmi1_value_reference_t vr = valueId;
+ status = fmi1_import_set_real((fmi1_import_t *)fmu, &vr, 1, &value);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ *error = "Error happened during setting real value!";
+ return 1;
+ }
+ return 0;
+}
+
+int FMI2_CS_SET_REAL(void *fmu, long valueId, double value, const char **error) {
+
+ fmi2_status_t status;
+
+ fmi2_value_reference_t vr = valueId;
+ status = fmi2_import_set_real((fmi2_import_t *)fmu, &vr, 1, &value);
+ if (status == fmi2_status_error || status == fmi2_status_fatal) {
+ *error = "Error happened during setting real value!";
+ return 1;
+ }
+ return 0;
+}
+
+double FMI1_CS_GET_REAL(void *fmu, int valueReference, const char **error) {
+
+ fmi1_value_reference_t vr = valueReference;
+ fmi1_real_t value;
+
+ fmi1_status_t status;
+
+ status = fmi1_import_get_real((fmi1_import_t *)fmu, &vr, 1, &value);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ *error = "Error happened during getting real value!";
+ }
+ return value;
+}
+
+double FMI2_CS_GET_REAL(void *fmu, int valueReference, const char **error) {
+
+ fmi2_value_reference_t vr = valueReference;
+ fmi2_real_t value;
+
+ fmi2_status_t status;
+
+ status = fmi2_import_get_real((fmi2_import_t *)fmu, &vr, 1, &value);
+ if (status == fmi2_status_error || status == fmi2_status_fatal) {
+ *error = "Error happened during setting real value!";
+ }
+ return value;
+}
+
+int FMI1_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count, const char **error) {
+
+ fmi1_value_reference_t *vrs = valueReferences;
+ fmi1_real_t value;
+
+ fmi1_status_t status;
+
+ status = fmi1_import_get_real((fmi1_import_t *)fmu, vrs, count, result);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ *error = "Error happened during getting reals value!";
+ }
+ return 0;
+}
+
+int FMI2_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count, const char **error) {
+
+ fmi2_value_reference_t *vrs = valueReferences;
+ fmi2_real_t value;
+
+ fmi2_status_t status;
+
+ status = fmi2_import_get_real((fmi2_import_t *)fmu, vrs, count, result);
+ if (status == fmi2_status_error || status == fmi2_status_fatal) {
+ *error = "Error happened during getting reals value!";
+ }
+ return 0;
+
+}