]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/native/FMILibrary/src/CAPI/src/FMI2/fmi2_capi.c
Switch to full JavaSE-11+ compatibility
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / src / CAPI / src / FMI2 / fmi2_capi.c
1 /*
2     Copyright (C) 2012 Modelon AB
3
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the BSD style license.
6
7      This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10     FMILIB_License.txt file for more details.
11
12     You should have received a copy of the FMILIB_License.txt file
13     along with this program. If not, contact Modelon AB <http://www.modelon.com>.
14 */
15
16 #include <stdio.h>
17 #include <stdarg.h>
18 #include <string.h>
19 #include <assert.h>
20
21 #include <JM/jm_types.h>
22 #include <JM/jm_portability.h>
23
24 #include <FMI2/fmi2_capi_impl.h>
25
26 #define FUNCTION_NAME_LENGTH_MAX 2048                   /* Maximum length of FMI function name. Used in the load DLL function. */
27 #define STRINGIFY(str) #str
28
29 /* Loading shared library functions */
30 static jm_status_enu_t fmi2_capi_get_fcn(fmi2_capi_t* fmu, const char* function_name, jm_dll_function_ptr* dll_function_ptrptr, jm_status_enu_t* status )
31 {
32                 jm_status_enu_t jm_status = jm_portability_load_dll_function(fmu->dllHandle, (char*)function_name, dll_function_ptrptr);
33                 if (jm_status == jm_status_error) {
34                         jm_log_error(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the FMI function '%s'. %s", function_name, jm_portability_get_last_dll_error()); 
35                         *status = jm_status_error;
36                 }
37                 return jm_status;
38 }
39
40 static void fmi2_capi_get_fcn_with_flag(fmi2_capi_t* fmu, const char* function_name, 
41                                                                                                         jm_dll_function_ptr* dll_function_ptrptr, 
42                                                                                                         unsigned int capabilities[],
43                                                                                                         fmi2_capabilities_enu_t flag) {
44         jm_status_enu_t status = jm_status_success;
45         if(capabilities[flag]) {
46                 fmi2_capi_get_fcn(fmu, function_name, dll_function_ptrptr, &status);
47                 if(status != jm_status_success) {
48                         jm_log_warning(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Resetting flag '%s'", fmi2_capability_to_string(flag)); 
49                         capabilities[flag] = 0;
50                 }
51         }
52 }
53
54 /* Load FMI functions from DLL macro */
55 #define LOAD_DLL_FUNCTION(FMIFUNCTION) fmi2_capi_get_fcn(fmu, #FMIFUNCTION, (jm_dll_function_ptr*)&fmu->FMIFUNCTION, &jm_status)
56
57 /* Load FMI functions from DLL macro for functions controlled by capability flags */
58 #define LOAD_DLL_FUNCTION_WITH_FLAG(FMIFUNCTION, FLAG) \
59         fmi2_capi_get_fcn_with_flag(fmu, #FMIFUNCTION, (jm_dll_function_ptr*)&fmu->FMIFUNCTION, capabilities, FLAG)
60
61 static jm_status_enu_t fmi2_capi_load_common_fcn(fmi2_capi_t* fmu, unsigned int capabilities[])
62 {
63         jm_status_enu_t jm_status = jm_status_success;
64         /***************************************************\r
65 Types for Common Functions\r
66 ****************************************************/\r
67 \r
68 /* Inquire version numbers of header files and setting logging status */\r
69 /*   typedef const char* fmi2GetTypesPlatformTYPE(void);\r
70    typedef const char* fmi2GetVersionTYPE(void);\r
71    typedef fmi2Status  fmi2SetDebugLoggingTYPE(fmi2Component, fmi2Boolean, size_t, const fmi2String[]); */\r
72 \r
73         LOAD_DLL_FUNCTION(fmi2GetTypesPlatform);
74         LOAD_DLL_FUNCTION(fmi2GetVersion);
75         LOAD_DLL_FUNCTION(fmi2SetDebugLogging);
76
77 /* Enter and exit initialization mode, terminate and reset */
78 /* typedef fmi2Status fmi2TerminateTYPE              (fmi2Component);
79    typedef fmi2Status fmi2ResetTYPE                  (fmi2Component); */
80         LOAD_DLL_FUNCTION(fmi2Terminate);
81         LOAD_DLL_FUNCTION(fmi2Reset);
82
83     /* Creation and destruction of instances and setting debug status */
84     /*typedef fmi2Component fmi2InstantiateTYPE (fmi2String, fmi2Type, fmi2String, fmi2String, const fmi2CallbackFunctions*, fmi2Boolean, fmi2Boolean);
85     typedef void          fmi2FreeInstanceTYPE(fmi2Component);*/
86     LOAD_DLL_FUNCTION(fmi2Instantiate);
87     LOAD_DLL_FUNCTION(fmi2FreeInstance);
88
89    /* typedef fmi2Status fmi2SetupExperimentTYPE        (fmi2Component, fmi2Boolean, fmi2Real, fmi2Real, fmi2Boolean, fmi2Real);
90    typedef fmi2Status fmi2EnterInitializationModeTYPE(fmi2Component);
91    typedef fmi2Status fmi2ExitInitializationModeTYPE (fmi2Component); */
92     LOAD_DLL_FUNCTION(fmi2SetupExperiment);
93     LOAD_DLL_FUNCTION(fmi2EnterInitializationMode);
94     LOAD_DLL_FUNCTION(fmi2ExitInitializationMode);
95
96         /* Getting and setting variable values */\r
97 /*   typedef fmi2Status fmi2GetRealTYPE   (fmi2Component, const fmi2ValueReference[], size_t, fmi2Real   []);\r
98    typedef fmi2Status fmi2GetIntegerTYPE(fmi2Component, const fmi2ValueReference[], size_t, fmi2Integer[]);\r
99    typedef fmi2Status fmi2GetBooleanTYPE(fmi2Component, const fmi2ValueReference[], size_t, fmi2Boolean[]);\r
100    typedef fmi2Status fmi2GetStringTYPE (fmi2Component, const fmi2ValueReference[], size_t, fmi2String []); */\r
101 \r
102         LOAD_DLL_FUNCTION(fmi2GetReal);
103         LOAD_DLL_FUNCTION(fmi2GetInteger);
104         LOAD_DLL_FUNCTION(fmi2GetBoolean);
105         LOAD_DLL_FUNCTION(fmi2GetString);
106 \r
107         /*   typedef fmi2Status fmi2SetRealTYPE   (fmi2Component, const fmi2ValueReference[], size_t, const fmi2Real   []);\r
108    typedef fmi2Status fmi2SetIntegerTYPE(fmi2Component, const fmi2ValueReference[], size_t, const fmi2Integer[]);\r
109    typedef fmi2Status fmi2SetBooleanTYPE(fmi2Component, const fmi2ValueReference[], size_t, const fmi2Boolean[]);\r
110    typedef fmi2Status fmi2SetStringTYPE (fmi2Component, const fmi2ValueReference[], size_t, const fmi2String []); */\r
111 \r
112         LOAD_DLL_FUNCTION(fmi2SetReal);
113         LOAD_DLL_FUNCTION(fmi2SetInteger);
114         LOAD_DLL_FUNCTION(fmi2SetBoolean);
115         LOAD_DLL_FUNCTION(fmi2SetString);
116 \r
117         return jm_status;
118 }
119
120 /* Load FMI 2.0 Co-Simulation functions */
121 static jm_status_enu_t fmi2_capi_load_cs_fcn(fmi2_capi_t* fmu, unsigned int capabilities[])
122 {
123         jm_status_enu_t jm_status = jm_status_success;
124
125         jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the co-simulation interface"); 
126
127         jm_status = fmi2_capi_load_common_fcn(fmu, capabilities);
128
129         /* Getting and setting the internal FMU state */\r
130 /*   typedef fmi2Status fmi2GetFMUstateTYPE           (fmi2Component, fmi2FMUstate*);\r
131    typedef fmi2Status fmi2SetFMUstateTYPE           (fmi2Component, fmi2FMUstate);\r
132    typedef fmi2Status fmi2FreeFMUstateTYPE          (fmi2Component, fmi2FMUstate*);\r
133    typedef fmi2Status fmi2SerializedFMUstateSizeTYPE(fmi2Component, fmi2FMUstate, size_t*);\r
134    typedef fmi2Status fmi2SerializeFMUstateTYPE     (fmi2Component, fmi2FMUstate, fmi2Byte[], size_t);\r
135    typedef fmi2Status fmi2DeSerializeFMUstateTYPE   (fmi2Component, const fmi2Byte[], size_t, fmi2FMUstate*); */\r
136    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetFMUstate,fmi2_cs_canGetAndSetFMUstate);\r
137    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SetFMUstate,fmi2_cs_canGetAndSetFMUstate);\r
138    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2FreeFMUstate,fmi2_cs_canGetAndSetFMUstate);\r
139    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializedFMUstateSize,fmi2_cs_canSerializeFMUstate);\r
140    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializeFMUstate,fmi2_cs_canSerializeFMUstate);\r
141    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2DeSerializeFMUstate,fmi2_cs_canSerializeFMUstate);\r
142 \r
143 /* Getting directional derivatives */\r
144 /*   typedef fmi2Status fmi2GetDirectionalDerivativeTYPE(fmi2Component, const fmi2ValueReference[], size_t,
145                                                                    const fmi2ValueReference[], size_t,
146                                                                    const fmi2Real[], fmi2Real[]);*/\r
147     LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetDirectionalDerivative,fmi2_cs_providesDirectionalDerivatives); \r
148
149 /* Simulating the slave */\r
150 /*   typedef fmi2Status fmi2SetRealInputDerivativesTYPE (fmi2Component, const fmi2ValueReference [], size_t, const fmi2Integer [], const fmi2Real []);\r
151    typedef fmi2Status fmi2GetRealOutputDerivativesTYPE(fmi2Component, const fmi2ValueReference [], size_t, const fmi2Integer [], fmi2Real []); */\r
152         LOAD_DLL_FUNCTION(fmi2SetRealInputDerivatives);
153         LOAD_DLL_FUNCTION(fmi2GetRealOutputDerivatives);
154 \r
155 /*   typedef fmi2Status fmi2DoStepTYPE     (fmi2Component, fmi2Real, fmi2Real, fmi2Boolean);\r
156    typedef fmi2Status fmi2CancelStepTYPE (fmi2Component); */\r
157         LOAD_DLL_FUNCTION(fmi2CancelStep);
158         LOAD_DLL_FUNCTION(fmi2DoStep);
159 \r
160 /* Inquire slave status */\r
161 /*   typedef fmi2Status fmi2GetStatusTYPE       (fmi2Component, const fmi2StatusKind, fmi2Status* );\r
162    typedef fmi2Status fmi2GetRealStatusTYPE   (fmi2Component, const fmi2StatusKind, fmi2Real*   );\r
163    typedef fmi2Status fmi2GetIntegerStatusTYPE(fmi2Component, const fmi2StatusKind, fmi2Integer*);\r
164    typedef fmi2Status fmi2GetBooleanStatusTYPE(fmi2Component, const fmi2StatusKind, fmi2Boolean*);\r
165    typedef fmi2Status fmi2GetStringStatusTYPE (fmi2Component, const fmi2StatusKind, fmi2String* ); */\r
166         LOAD_DLL_FUNCTION(fmi2GetStatus);
167         LOAD_DLL_FUNCTION(fmi2GetRealStatus);
168         LOAD_DLL_FUNCTION(fmi2GetIntegerStatus);
169         LOAD_DLL_FUNCTION(fmi2GetBooleanStatus);
170         LOAD_DLL_FUNCTION(fmi2GetStringStatus);
171
172         return jm_status; 
173 }
174
175 /* Load FMI 2.0 Model Exchange functions */
176 static jm_status_enu_t fmi2_capi_load_me_fcn(fmi2_capi_t* fmu, unsigned int capabilities[])
177 {
178         jm_status_enu_t jm_status = jm_status_success;
179
180         jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the model exchange interface"); 
181
182         jm_status = fmi2_capi_load_common_fcn(fmu, capabilities);
183                 /* Getting and setting the internal FMU state */\r
184 /*   typedef fmi2Status fmi2GetFMUstateTYPE           (fmi2Component, fmi2FMUstate*);\r
185    typedef fmi2Status fmi2SetFMUstateTYPE           (fmi2Component, fmi2FMUstate);\r
186    typedef fmi2Status fmi2FreeFMUstateTYPE          (fmi2Component, fmi2FMUstate*);\r
187    typedef fmi2Status fmi2SerializedFMUstateSizeTYPE(fmi2Component, fmi2FMUstate, size_t*);\r
188    typedef fmi2Status fmi2SerializeFMUstateTYPE     (fmi2Component, fmi2FMUstate, fmi2Byte[], size_t);\r
189    typedef fmi2Status fmi2DeSerializeFMUstateTYPE   (fmi2Component, const fmi2Byte[], size_t, fmi2FMUstate*); */\r
190    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetFMUstate,fmi2_me_canGetAndSetFMUstate);\r
191    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SetFMUstate,fmi2_me_canGetAndSetFMUstate);\r
192    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2FreeFMUstate,fmi2_me_canGetAndSetFMUstate);\r
193    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializedFMUstateSize,fmi2_me_canSerializeFMUstate);\r
194    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializeFMUstate,fmi2_me_canSerializeFMUstate);\r
195    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2DeSerializeFMUstate,fmi2_me_canSerializeFMUstate);\r
196 \r
197 /* Getting directional derivatives */\r
198 /*   typedef fmi2Status fmi2GetDirectionalDerivativeTYPE(fmi2Component, const fmi2ValueReference[], size_t,
199                                                                    const fmi2ValueReference[], size_t,
200                                                                    const fmi2Real[], fmi2Real[]); */\r
201     LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetDirectionalDerivative,fmi2_me_providesDirectionalDerivatives); \r
202
203 /* Enter and exit the different modes */
204 /*   typedef fmi2Status fmi2EnterEventModeTYPE         (fmi2Component);
205    typedef fmi2Status fmi2NewDiscreteStatesTYPE      (fmi2Component, fmi2EventInfo*);
206    typedef fmi2Status fmi2EnterContinuousTimeModeTYPE(fmi2Component);
207    typedef fmi2Status fmi2CompletedIntegratorStepTYPE(fmi2Component, fmi2Boolean, fmi2Boolean*, fmi2Boolean*);*/
208         LOAD_DLL_FUNCTION(fmi2EnterEventMode);
209         LOAD_DLL_FUNCTION(fmi2NewDiscreteStates);
210         LOAD_DLL_FUNCTION(fmi2EnterContinuousTimeMode);
211         LOAD_DLL_FUNCTION(fmi2CompletedIntegratorStep);
212
213 /* Providing independent variables and re-initialization of caching */\r
214    /*typedef fmi2Status fmi2SetTimeTYPE            (fmi2Component, fmi2Real);\r
215    typedef fmi2Status fmi2SetContinuousStatesTYPE(fmi2Component, const fmi2Real[], size_t);*/
216         LOAD_DLL_FUNCTION(fmi2SetTime);
217         LOAD_DLL_FUNCTION(fmi2SetContinuousStates);
218 \r
219 /* Evaluation of the model equations */
220
221 /*\r
222    typedef fmi2Status fmi2GetDerivativesTYPE               (fmi2Component, fmi2Real[], size_t);\r
223    typedef fmi2Status fmi2GetEventIndicatorsTYPE           (fmi2Component, fmi2Real[], size_t);\r
224    typedef fmi2Status fmi2GetContinuousStatesTYPE          (fmi2Component, fmi2Real[], size_t);\r
225    typedef fmi2Status fmi2GetNominalsOfContinuousStatesTYPE(fmi2Component, fmi2Real[], size_t);*/
226         LOAD_DLL_FUNCTION(fmi2GetDerivatives);
227         LOAD_DLL_FUNCTION(fmi2GetEventIndicators);
228         LOAD_DLL_FUNCTION(fmi2GetContinuousStates);
229         LOAD_DLL_FUNCTION(fmi2GetNominalsOfContinuousStates);
230    
231         return jm_status; 
232 }
233
234 void fmi2_capi_destroy_dllfmu(fmi2_capi_t* fmu)
235 {
236         if (fmu == NULL) {
237                 return;
238         }
239         fmi2_capi_free_dll(fmu);
240         jm_log_debug(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Releasing allocated memory");
241         fmu->callbacks->free((void*)fmu->dllPath);
242         fmu->callbacks->free((void*)fmu->modelIdentifier);
243         fmu->callbacks->free((void*)fmu);
244 }
245
246 fmi2_capi_t* fmi2_capi_create_dllfmu(jm_callbacks* cb, const char* dllPath, const char* modelIdentifier, const fmi2_callback_functions_t* callBackFunctions, fmi2_fmu_kind_enu_t standard)
247 {
248         fmi2_capi_t* fmu = NULL;
249
250         jm_log_debug(cb, FMI_CAPI_MODULE_NAME, "Initializing data structures for FMICAPI.");
251
252         /* Minor check for the callbacks */
253         if (cb == NULL) {
254                 assert(0);
255                 return NULL;
256         }
257
258         /* Allocate memory for the FMU instance */
259         fmu = (fmi2_capi_t*)cb->calloc(1, sizeof(fmi2_capi_t));
260         if (fmu == NULL) { /* Could not allocate memory for the FMU struct */
261                 jm_log_fatal(cb, FMI_CAPI_MODULE_NAME, "Could not allocate memory for the FMU struct.");
262                 return NULL;
263         }
264
265         /* Set the import package callback functions */
266         fmu->callbacks = cb;
267
268         /* Set the FMI callback functions */
269         fmu->callBackFunctions = *callBackFunctions;
270
271         /* Set FMI standard to load */
272         fmu->standard = standard;
273
274         /* Set all memory alloated pointers to NULL */
275         fmu->dllPath = NULL;
276         fmu->modelIdentifier = NULL;
277
278
279         /* Copy DLL path */
280         fmu->dllPath = (char*)cb->calloc(sizeof(char), strlen(dllPath) + 1);
281         if (fmu->dllPath == NULL) {
282                 jm_log_fatal(cb, FMI_CAPI_MODULE_NAME, "Could not allocate memory for the DLL path string.");
283                 fmi2_capi_destroy_dllfmu(fmu);
284                 return NULL;
285         }
286         strcpy((char*)fmu->dllPath, dllPath);
287
288         /* Copy the modelIdentifier */
289         fmu->modelIdentifier = (char*)cb->calloc(sizeof(char), strlen(modelIdentifier) + 1);
290         if (fmu->modelIdentifier == NULL) {
291                 jm_log_fatal(cb, FMI_CAPI_MODULE_NAME, "Could not allocate memory for the modelIdentifier string.");
292                 fmi2_capi_destroy_dllfmu(fmu);
293                 return NULL;
294         }
295         strcpy((char*)fmu->modelIdentifier, modelIdentifier);
296
297         jm_log_debug(cb, FMI_CAPI_MODULE_NAME, "Successfully initialized data structures for FMICAPI.");
298
299         /* Everything was successful */
300         return fmu;
301 }
302
303 jm_status_enu_t fmi2_capi_load_fcn(fmi2_capi_t* fmu, unsigned int capabilities[])
304 {
305         assert(fmu);
306         /* Load ME functions */
307         if (fmu->standard == fmi2_fmu_kind_me) {
308                 return fmi2_capi_load_me_fcn(fmu, capabilities);
309         /* Load CS functions */
310         } else if (fmu->standard == fmi2_fmu_kind_cs) {
311                 return fmi2_capi_load_cs_fcn(fmu, capabilities);
312         } else {
313                 jm_log_error(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Unexpected FMU kind in FMICAPI.");
314                 return jm_status_error;
315         }
316 }
317
318 jm_status_enu_t fmi2_capi_load_dll(fmi2_capi_t* fmu)
319 {
320         assert(fmu && fmu->dllPath);
321         fmu->dllHandle = jm_portability_load_dll_handle(fmu->dllPath); /* Load the shared library */
322         if (fmu->dllHandle == NULL) {
323                 jm_log_fatal(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the DLL: %s", jm_portability_get_last_dll_error());
324                 return jm_status_error;
325         } else {
326                 jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loaded FMU binary from %s", fmu->dllPath);
327                 return jm_status_success;
328         }
329 }
330
331 void fmi2_capi_set_debug_mode(fmi2_capi_t* fmu, int mode) {
332         if(fmu)
333                 fmu->debugMode = mode;
334 }
335 \r
336 int fmi2_capi_get_debug_mode(fmi2_capi_t* fmu) {
337         if(fmu) return fmu->debugMode;
338         return 0;
339 }
340
341 fmi2_fmu_kind_enu_t fmi2_capi_get_fmu_kind(fmi2_capi_t* fmu) {
342         if(fmu) return fmu->standard;
343         return fmi2_fmu_kind_unknown;
344 }
345
346 jm_status_enu_t fmi2_capi_free_dll(fmi2_capi_t* fmu)
347 {
348         if (fmu == NULL) {              
349                 return jm_status_error; /* Return without writing any log message */
350         }
351
352         if (fmu->dllHandle) {
353                 jm_status_enu_t status =
354                         (fmu->debugMode != 0) ?
355                 /* When running valgrind this may be convenient to track mem leaks */ 
356                 jm_status_success:
357                 jm_portability_free_dll_handle(fmu->dllHandle);
358                 fmu->dllHandle = 0;
359                 if (status == jm_status_error) { /* Free the library handle */
360                         jm_log(fmu->callbacks, FMI_CAPI_MODULE_NAME, jm_log_level_error, "Could not free the DLL: %s", jm_portability_get_last_dll_error());
361                         return jm_status_error;
362                 } else {
363                         jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Successfully unloaded FMU binary");
364                         return jm_status_success;
365                 }
366         }
367         return jm_status_success;
368 }
369
370 /* Common FMI 2.0 functions */
371
372 const char* fmi2_capi_get_version(fmi2_capi_t* fmu)
373 {
374         assert(fmu);
375         return fmu->fmi2GetVersion();
376 }
377 \r
378 const char* fmi2_capi_get_types_platform(fmi2_capi_t* fmu)\r
379 {\r
380         assert(fmu);\r
381         jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2GetModelTypesPlatform");\r
382         return fmu->fmi2GetTypesPlatform();\r
383 }\r
384
385 fmi2_status_t fmi2_capi_set_debug_logging(fmi2_capi_t* fmu, fmi2_boolean_t loggingOn, size_t nCategories, fmi2_string_t categories[])
386 {
387         return fmu->fmi2SetDebugLogging(fmu->c, loggingOn, nCategories, categories);
388 }
389
390 fmi2_component_t fmi2_capi_instantiate(fmi2_capi_t* fmu,
391   fmi2_string_t instanceName, fmi2_type_t fmuType, fmi2_string_t fmuGUID,
392   fmi2_string_t fmuResourceLocation, fmi2_boolean_t visible,
393   fmi2_boolean_t loggingOn)
394 {
395     return fmu->c = fmu->fmi2Instantiate(instanceName, fmuType, fmuGUID,
396         fmuResourceLocation, &fmu->callBackFunctions, visible, loggingOn);
397 }
398
399 void fmi2_capi_free_instance(fmi2_capi_t* fmu)
400 {
401     if(fmu != NULL && fmu->c != NULL) {
402         fmu->fmi2FreeInstance(fmu->c);
403         fmu->c = 0;
404     }
405 }
406
407
408 fmi2_status_t fmi2_capi_setup_experiment(fmi2_capi_t* fmu,
409     fmi2_boolean_t tolerance_defined, fmi2_real_t tolerance,
410     fmi2_real_t start_time, fmi2_boolean_t stop_time_defined,
411     fmi2_real_t stop_time)
412 {
413     assert(fmu); assert(fmu->c);
414     jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2SetupExperiment");
415     return fmu->fmi2SetupExperiment(fmu->c, tolerance_defined, tolerance,
416                                    start_time, stop_time_defined, stop_time);
417 }
418
419 fmi2_status_t fmi2_capi_enter_initialization_mode(fmi2_capi_t* fmu)
420 {
421     assert(fmu); assert(fmu->c);
422     jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2EnterInitializationMode");
423     return fmu->fmi2EnterInitializationMode(fmu->c);
424 }
425
426 fmi2_status_t fmi2_capi_exit_initialization_mode(fmi2_capi_t* fmu)
427 {
428     assert(fmu); assert(fmu->c);
429     jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2ExitInitializationMode");
430     return fmu->fmi2ExitInitializationMode(fmu->c);
431 }
432
433
434 fmi2_status_t fmi2_capi_terminate(fmi2_capi_t* fmu)
435 {
436         assert(fmu);
437         jm_log_debug(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2Terminate");
438         return fmu->fmi2Terminate(fmu->c);
439 }
440
441 fmi2_status_t fmi2_capi_reset(fmi2_capi_t* fmu)
442 {
443         return fmu->fmi2Reset(fmu->c);
444 }
445
446 fmi2_status_t fmi2_capi_get_fmu_state           (fmi2_capi_t* fmu, fmi2_FMU_state_t* s) {\r
447         return fmu->fmi2GetFMUstate(fmu -> c,s);\r
448 }\r
449 fmi2_status_t fmi2_capi_set_fmu_state           (fmi2_capi_t* fmu, fmi2_FMU_state_t s){\r
450         return fmu->fmi2SetFMUstate(fmu -> c,s);\r
451 }\r
452 fmi2_status_t fmi2_capi_free_fmu_state          (fmi2_capi_t* fmu, fmi2_FMU_state_t* s){\r
453         return fmu->fmi2FreeFMUstate (fmu -> c,s);\r
454 }\r
455 fmi2_status_t fmi2_capi_serialized_fmu_state_size(fmi2_capi_t* fmu, fmi2_FMU_state_t s, size_t* sz){\r
456         return fmu->fmi2SerializedFMUstateSize(fmu -> c,s,sz);\r
457 }\r
458 fmi2_status_t fmi2_capi_serialize_fmu_state     (fmi2_capi_t* fmu, fmi2_FMU_state_t s , fmi2_byte_t data[], size_t sz){\r
459         return fmu->fmi2SerializeFMUstate(fmu -> c,s,data,sz);\r
460 }\r
461 fmi2_status_t fmi2_capi_de_serialize_fmu_state  (fmi2_capi_t* fmu, const fmi2_byte_t data[], size_t sz, fmi2_FMU_state_t* s){\r
462         return fmu->fmi2DeSerializeFMUstate (fmu -> c,data,sz,s);\r
463 }\r
464 \r
465 fmi2_status_t fmi2_capi_get_directional_derivative(fmi2_capi_t* fmu, const fmi2_value_reference_t v_ref[], size_t nv,\r
466                                                                    const fmi2_value_reference_t z_ref[], size_t nz,\r
467                                                                    const fmi2_real_t dv[], fmi2_real_t dz[]){\r
468         return fmu->fmi2GetDirectionalDerivative(fmu -> c, z_ref, nz, v_ref, nv, dv, dz);\r
469 }
470
471
472 /* fmiSet* functions */
473 #define FMISETX(FNAME1, FNAME2, FTYPE) \
474 fmi2_status_t FNAME1(fmi2_capi_t* fmu, const fmi2_value_reference_t vr[], size_t nvr, const FTYPE value[])      \
475 { \
476         return fmu->FNAME2(fmu->c, vr, nvr, value); \
477 }
478
479 /* fmiGet* functions */
480 #define FMIGETX(FNAME1, FNAME2, FTYPE) \
481 fmi2_status_t FNAME1(fmi2_capi_t* fmu, const fmi2_value_reference_t vr[], size_t nvr, FTYPE value[]) \
482 { \
483         return fmu->FNAME2(fmu->c, vr, nvr, value); \
484 }
485
486 FMISETX(fmi2_capi_set_real,             fmi2SetReal,            fmi2_real_t)
487 FMISETX(fmi2_capi_set_integer,  fmi2SetInteger, fmi2_integer_t)
488 FMISETX(fmi2_capi_set_boolean,  fmi2SetBoolean, fmi2_boolean_t)
489 FMISETX(fmi2_capi_set_string,   fmi2SetString,  fmi2_string_t)
490
491 FMIGETX(fmi2_capi_get_real,     fmi2GetReal,            fmi2_real_t)
492 FMIGETX(fmi2_capi_get_integer,  fmi2GetInteger, fmi2_integer_t)
493 FMIGETX(fmi2_capi_get_boolean,  fmi2GetBoolean, fmi2_boolean_t)
494 FMIGETX(fmi2_capi_get_string,   fmi2GetString,  fmi2_string_t)