]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/native/FMUSimulator/fmi_util.c.txt
bfd6e203a552bb8144e48862945e32b5e3ce9180
[simantics/fmil.git] / org.simantics.fmil.core / native / FMUSimulator / fmi_util.c.txt
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 <assert.h>
17 #include <string.h>
18 #include <stdio.h>
19 #include <FMI/fmi_util.h>
20 #include <FMI/fmi_zip_unzip.h>
21
22
23 char* fmi_construct_dll_dir_name(jm_callbacks* callbacks, const char* fmu_unzipped_path) {
24         char* dir_path;
25         size_t len;
26
27         assert( fmu_unzipped_path && callbacks);
28
29         len = 
30                 strlen(fmu_unzipped_path) + strlen(FMI_FILE_SEP)
31                 + strlen(FMI_BINARIES) + strlen(FMI_FILE_SEP) 
32                 + strlen(FMI_PLATFORM) + strlen(FMI_FILE_SEP) + 1;
33
34         dir_path = (char*)callbacks->malloc(len);
35         if (dir_path == NULL) {
36                 jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
37                 return NULL;
38         }
39
40         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 */
41
42         return dir_path;
43 }
44
45 char* fmi_construct_dll_file_name(jm_callbacks* callbacks, const char* dll_dir_name, const char* model_identifier) {
46         char* fname;
47         size_t len;
48         assert(callbacks && model_identifier);
49         len = 
50                 strlen(dll_dir_name) +
51                 strlen(model_identifier) 
52                 + strlen(FMI_DLL_EXT) + 1;
53         fname = (char*)callbacks->malloc(len);
54         if (fname == NULL) {
55                 jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
56                 return NULL;
57         }
58         sprintf(fname, "%s%s%s", dll_dir_name, model_identifier, FMI_DLL_EXT);/*safe */
59
60         return fname;
61 }
62
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <stdarg.h>
66 #include <string.h>
67 #include <errno.h>
68
69 #include <fmilib.h>
70
71 #ifdef __cplusplus
72 extern "C" {
73 #endif
74
75 typedef struct {
76         char *name;
77         char *description;
78         char *declaredType;
79         long vr;
80         /* 0 = real
81         // 1 = integer
82         // 2 = boolean
83         // 3 = string
84         // 4 = enumeration */
85         int type;
86         /* 0 = constant
87         // 1 = parameter
88         // 2 = discrete
89         // 3 = continuous
90         // 4 = unknown */
91         int variability;
92         /* 0 = input
93         // 1 = output
94         // 2 = internal
95         // 3 = none
96         // 4 = unknown */
97         int causality;
98 } FMIL_Variable;
99
100 typedef struct {
101         char *name;
102         char *description;
103         char *quantity;
104         char *unit;
105 } FMIL_DeclaredType;
106
107 #ifdef _MSC_VER
108 #define DLLEXPORT __declspec(dllexport)
109 #elif __GNUC__
110 #define DLLEXPORT __attribute__((visibility("default")))
111 #pragma warning Using GNUC default visibility
112 #else
113 #define DLLEXPORT
114 #pragma warning Empty dynamic link EXPORT defined
115 #endif
116
117 DLLEXPORT int FMI_CS_LOAD(const char *zipFilePath, const char *unzipFolder, void **fmuPointer, int *fmuVersion, const char **error);
118
119 DLLEXPORT int FMI1_CS_UNLOAD(void* fmu, const char **error);
120 DLLEXPORT FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
121 DLLEXPORT FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
122 DLLEXPORT int FMI1_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
123 DLLEXPORT int FMI1_CS_INITIALIZE(void* fmu, const char **error);
124 DLLEXPORT int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
125 DLLEXPORT int FMI1_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
126 DLLEXPORT double FMI1_CS_GET_REAL(void* fmu, int vr, const char **error);
127 DLLEXPORT int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
128
129 DLLEXPORT int FMI2_CS_UNLOAD(void* fmu, const char **error);
130 DLLEXPORT FMIL_Variable *FMI2_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
131 DLLEXPORT FMIL_DeclaredType *FMI2_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
132 DLLEXPORT int FMI2_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
133 DLLEXPORT int FMI2_CS_INITIALIZE(void* fmu, const char **error);
134 DLLEXPORT int FMI2_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
135 DLLEXPORT int FMI2_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
136 DLLEXPORT double FMI2_CS_GET_REAL(void* fmu, int vr, const char **error);
137 DLLEXPORT int FMI2_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
138
139 #ifdef __cplusplus
140 }
141 #endif
142
143 #define BUFFER 4096
144
145 /* Logger function used by the C-API */
146 void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
147 {
148         printf("module = %s, log level = %d: %s\n", module, log_level, message);
149 }
150
151 /* Logger function used by the FMU internally */
152 void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)
153 {
154         char msg[BUFFER];
155     int len;
156         va_list argp;   
157         va_start(argp, message);
158         /*len=jm_vsnprintf(msg, BUFFER, message, argp);
159         printf("fmiStatus = %d;  %s (%s): %s\n", status, instanceName, category, msg);
160     if(len > BUFFER) {
161         printf("Warning: message was trancated");
162     }*/
163 }
164
165 int FMI_CS_LOAD(const char *zipFilePath, const char *unzipFolder, void **fmuPointer, int *fmuVersion, const char **error) {
166
167         fmi1_callback_functions_t callBackFunctions;
168         fmi2_callback_functions_t callBackFunctions2;
169         fmi_import_context_t* context;
170         fmi_version_enu_t version;
171     jm_status_enu_t status;
172         fmi1_import_t *fmu;
173         fmi2_import_t *fmu2;
174         jm_callbacks* callbacks;
175
176         callbacks = (jm_callbacks *)calloc(1, sizeof(jm_callbacks));
177
178         callbacks->malloc = malloc;
179     callbacks->calloc = calloc;
180     callbacks->realloc = realloc;
181     callbacks->free = free;
182     callbacks->logger = importlogger;
183     callbacks->log_level = jm_log_level_debug;
184     callbacks->context = 0;
185
186         context = fmi_import_allocate_context(callbacks);
187
188         version = fmi_import_get_fmi_version(context, zipFilePath, unzipFolder);
189
190         if (version == fmi_version_1_enu ) {
191                 fmu = fmi1_import_parse_xml(context, unzipFolder);
192                 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) {
193                         *error = "Provided FMU is version 1 but wrong type me (Model Exchange) when it should be cs (Co-Simulation)";
194                         return 2; /* wrong type, should be co-simulation */
195                 }
196                 
197                 callBackFunctions.logger = fmilogger;
198                 callBackFunctions.allocateMemory = calloc;
199                 callBackFunctions.freeMemory = free;
200
201                 status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 0);
202                 if (status == jm_status_error) {
203                         *error = fmi1_import_get_last_error(fmu);
204                         return 3;
205                 }
206
207                 *fmuPointer = fmu;
208                 *fmuVersion = 1;
209         } else if (version == fmi_version_2_0_enu) {
210                 fmu2 = fmi2_import_parse_xml(context, unzipFolder, 0);
211
212                 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) {
213                         *error = "Provided FMU is version 2.0 but wrong type me (Model Exchange) when it should be cs (Co-Simulation)";
214                         return 2; /* wrong type, should be co-simulation */
215                 }
216
217                 callBackFunctions2.logger = fmi2_log_forwarding;
218                 callBackFunctions2.allocateMemory = calloc;
219                 callBackFunctions2.freeMemory = free;
220                 callBackFunctions2.componentEnvironment = fmu2;
221
222                 status = fmi2_import_create_dllfmu(fmu2, fmi2_fmu_kind_cs, &callBackFunctions2);
223                 if (status == jm_status_error) {
224                         *error = fmi2_import_get_last_error(fmu2);
225                         return 3;
226                 }
227                 
228                 *fmuPointer = fmu2;
229                 *fmuVersion = 2;
230         }
231         
232         fmi_import_free_context(context);
233
234         return 0; /* success */
235 }
236
237 int FMI1_CS_UNLOAD(void *fmu_, const char **error) {
238         fmi1_import_t *fmu = (fmi1_import_t *)fmu_;
239         fmi1_import_destroy_dllfmu(fmu);
240         fmi1_import_free(fmu);
241         return 0;
242 }
243
244 int FMI2_CS_UNLOAD(void *fmu_, const char **error) {
245         fmi2_import_t *fmu = (fmi2_import_t *)fmu_;
246         fmi2_import_destroy_dllfmu(fmu);
247         fmi2_import_free(fmu);
248         return 0;
249 }
250
251 /*
252  if(!vt) {
253         printf("No type definition\n");
254         return;
255     }
256
257     quan = fmi1_import_get_type_quantity(vt);
258
259     printf("Type %s\n description: %s\n",  fmi1_import_get_type_name(vt), fmi1_import_get_type_description(vt));
260
261     printf("Base type: %s\n", fmi1_base_type_to_string(fmi1_import_get_base_type(vt)));
262
263     if(quan) {
264         printf("Quantity: %s\n", quan);
265     }
266     switch(fmi1_import_get_base_type(vt)) {
267     case fmi1_base_type_real: {
268         fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(vt);
269         fmi1_real_t min = fmi1_import_get_real_type_min(rt);
270         fmi1_real_t max = fmi1_import_get_real_type_max(rt);
271         fmi1_real_t nom = fmi1_import_get_real_type_nominal(rt);
272         fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);
273         fmi1_import_display_unit_t* du = fmi1_import_get_type_display_unit(rt);
274
275         printf("Min %g, max %g, nominal %g\n", min, max, nom);
276
277         if(u) {
278             printf("Unit: %s\n", fmi1_import_get_unit_name(u));
279         }
280         if(du) {
281             printf("Display unit: %s, gain: %g, offset: %g, is relative: %s",
282                    fmi1_import_get_display_unit_name(du),
283                    fmi1_import_get_display_unit_gain(du),
284                    fmi1_import_get_display_unit_offset(du),
285                    fmi1_import_get_real_type_is_relative_quantity(rt)?"yes":"no"
286                    );
287         }
288
289         break;
290     }
291     case fmi1_base_type_int:{
292         fmi1_import_integer_typedef_t* it = fmi1_import_get_type_as_int(vt);
293         int min = fmi1_import_get_integer_type_min(it);
294         int max = fmi1_import_get_integer_type_max(it);
295         printf("Min %d, max %d\n", min, max);
296         break;
297     }
298     case fmi1_base_type_bool:{
299         break;
300     }
301     case fmi1_base_type_str:{
302         break;
303     }
304     case fmi1_base_type_enum:{
305         fmi1_import_enumeration_typedef_t* et = fmi1_import_get_type_as_enum(vt);
306         int min = fmi1_import_get_enum_type_min(et);
307         int max = fmi1_import_get_enum_type_max(et);
308         printf("Min %d, max %d\n", min, max);
309         {
310             size_t ni;
311                         unsigned i;
312             ni = fmi1_import_get_enum_type_size(et);
313                         i = (unsigned)(ni);
314                         assert( i == ni);
315             printf("There are %u items \n",(unsigned)ni);
316             for(i = 0; i < ni; i++) {
317                 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));
318             }
319         }
320         break;
321     }
322     default:
323         printf("Error in fmiGetBaseType()\n");
324     }
325 */
326
327
328 FMIL_Variable *FMI1_CS_GET_VARIABLES(void *fmu, int *count, const char **error) {
329
330     int i;
331         FMIL_Variable *result;
332     fmi1_import_variable_list_t* vl = fmi1_import_get_variable_list((fmi1_import_t *)fmu);
333         fmi1_import_variable_typedef_t* type;
334
335     count[0] = fmi1_import_get_variable_list_size(vl);
336
337         result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));
338
339     for(i = 0; i < count[0]; i++) {
340
341         fmi1_import_variable_t* var = fmi1_import_get_variable(vl, i);
342         if(!var) {
343
344                         printf("Something wrong with variable %d \n",i);
345                         return 0;
346
347                 } else {
348
349                         result[i].name = fmi1_import_get_variable_name(var);
350                         result[i].description = fmi1_import_get_variable_description(var);
351
352                         switch  (fmi1_import_get_variability(var)) {
353                         case fmi1_variability_enu_constant:
354                                 result[i].variability = 0;
355                                 break;
356                         case fmi1_variability_enu_parameter:
357                                 result[i].variability = 1;
358                                 break;
359                         case fmi1_variability_enu_discrete:
360                                 result[i].variability = 2;
361                                 break;
362                         case fmi1_variability_enu_continuous:
363                                 result[i].variability = 3;
364                                 break;
365                         case fmi1_variability_enu_unknown:
366                                 result[i].variability = 4;
367                                 break;
368                         }
369
370                         switch  (fmi1_import_get_causality(var)) {
371                         case fmi1_causality_enu_input:
372                                 result[i].causality = 0;
373                                 break;
374                         case fmi1_causality_enu_output:
375                                 result[i].causality = 1;
376                                 break;
377                         case fmi1_causality_enu_internal:
378                                 result[i].causality = 2;
379                                 break;
380                         case fmi1_causality_enu_none:
381                                 result[i].causality = 3;
382                                 break;
383                         case fmi1_causality_enu_unknown:
384                                 result[i].causality = 4;
385                                 break;
386                         }
387
388                         switch  (fmi1_import_get_variable_base_type(var)) {
389                         case fmi1_base_type_real:
390                                 result[i].type = 0;
391                                 break;
392                         case fmi1_base_type_int:
393                                 result[i].type = 1;
394                                 break;
395                         case fmi1_base_type_bool:
396                                 result[i].type = 2;
397                                 break;
398                         case fmi1_base_type_str:
399                                 result[i].type = 3;
400                                 break;
401                         case fmi1_base_type_enum:
402                                 result[i].type = 4;
403                                 break;
404                         }
405                         
406                         result[i].vr = fmi1_import_get_variable_vr(var);
407
408                         type = fmi1_import_get_variable_declared_type(var);
409                         if(type) {
410                                 result[i].declaredType = fmi1_import_get_type_name(type);
411                         } else {
412                                 result[i].declaredType = 0;
413                         }
414
415                 }
416
417     }
418
419     fmi1_import_free_variable_list(vl);
420
421         return result;
422
423 }
424
425 FMIL_Variable *FMI2_CS_GET_VARIABLES(void *fmu, int *count, const char **error) {
426
427     int i;
428         FMIL_Variable *result;
429     fmi2_import_variable_list_t* vl = fmi2_import_get_variable_list((fmi2_import_t *)fmu, 0);
430         fmi2_import_variable_typedef_t* type;
431
432     count[0] = fmi2_import_get_variable_list_size(vl);
433
434         result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));
435
436     for(i = 0; i < count[0]; i++) {
437
438         fmi2_import_variable_t* var = fmi2_import_get_variable(vl, i);
439         if(!var) {
440
441                         printf("Something wrong with variable %d \n",i);
442                         return 0;
443
444                 } else {
445
446                         result[i].name = fmi2_import_get_variable_name(var);
447                         result[i].description = fmi2_import_get_variable_description(var);
448
449                         switch  (fmi2_import_get_variability(var)) {
450                         case fmi2_variability_enu_constant:
451                                 result[i].variability = 0;
452                                 break;
453                         case fmi2_variability_enu_fixed:
454                         case fmi2_variability_enu_tunable:
455                                 result[i].variability = 1;
456                                 break;
457                         case fmi2_variability_enu_discrete:
458                                 result[i].variability = 2;
459                                 break;
460                         case fmi2_variability_enu_continuous:
461                                 result[i].variability = 3;
462                                 break;
463                         case fmi2_variability_enu_unknown:
464                                 result[i].variability = 4;
465                                 break;
466                         }
467
468                         switch  (fmi2_import_get_causality(var)) {
469                         case fmi2_causality_enu_input:
470                                 result[i].causality = 0;
471                                 break;
472                         case fmi2_causality_enu_output:
473                                 result[i].causality = 1;
474                                 break;
475                         case fmi2_causality_enu_local:
476                                 result[i].causality = 2;
477                                 break;
478                         case fmi2_causality_enu_independent:
479                                 result[i].causality = 3;
480                                 break;
481                         case fmi2_causality_enu_unknown:
482                                 result[i].causality = 4;
483                                 break;
484                         }
485
486                         switch  (fmi2_import_get_variable_base_type(var)) {
487                         case fmi2_base_type_real:
488                                 result[i].type = 0;
489                                 break;
490                         case fmi2_base_type_int:
491                                 result[i].type = 1;
492                                 break;
493                         case fmi2_base_type_bool:
494                                 result[i].type = 2;
495                                 break;
496                         case fmi2_base_type_str:
497                                 result[i].type = 3;
498                                 break;
499                         case fmi2_base_type_enum:
500                                 result[i].type = 4;
501                                 break;
502                         }
503                         
504                         result[i].vr = fmi2_import_get_variable_vr(var);
505
506                         type = fmi2_import_get_variable_declared_type(var);
507                         if(type) {
508                                 result[i].declaredType = fmi2_import_get_type_name(type);
509                         } else {
510                                 result[i].declaredType = 0;
511                         }
512
513                 }
514
515     }
516
517     fmi2_import_free_variable_list(vl);
518
519         return result;
520
521 }
522
523 FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void *fmu, int *count, const char **error) {
524
525         FMIL_DeclaredType *result;
526     fmi1_import_type_definitions_t* td = fmi1_import_get_type_definitions((fmi1_import_t *)fmu);
527         fmi1_import_variable_typedef_t* type;
528     unsigned i, ntd = (unsigned)fmi1_import_get_type_definition_number(td);
529
530     count[0] = ntd;
531
532         result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));
533
534     for(i = 0; i < ntd; i++) {
535       type = fmi1_import_get_typedef(td, i);
536       result[i].name = fmi1_import_get_type_name(type);
537       result[i].description = fmi1_import_get_type_description(type);
538           result[i].quantity = fmi1_import_get_type_quantity(type);
539       result[i].unit = 0;
540
541           switch(fmi1_import_get_base_type(type)) {
542                    case fmi1_base_type_real: {
543                                 fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(type);
544                         fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);
545                                 if(u) result[i].unit = fmi1_import_get_unit_name(u);
546                    }
547           }
548
549     }
550
551         return result;
552
553 }
554
555 FMIL_DeclaredType *FMI2_CS_GET_DECLARED_TYPES(void *fmu, int *count, const char **error) {
556
557         FMIL_DeclaredType *result;
558     fmi2_import_type_definitions_t* td = fmi2_import_get_type_definitions((fmi2_import_t *)fmu);
559         fmi2_import_variable_typedef_t* type;
560     unsigned i, ntd = (unsigned)fmi2_import_get_type_definition_number(td);
561
562     count[0] = ntd;
563
564         result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));
565
566     for(i = 0; i < ntd; i++) {
567       type = fmi2_import_get_typedef(td, i);
568       result[i].name = fmi2_import_get_type_name(type);
569       result[i].description = fmi2_import_get_type_description(type);
570           result[i].quantity = fmi2_import_get_type_quantity(type);
571       result[i].unit = 0;
572
573           switch(fmi2_import_get_base_type(type)) {
574                    case fmi2_base_type_real: {
575                                 fmi2_import_real_typedef_t* rt = fmi2_import_get_type_as_real(type);
576                         fmi2_import_unit_t* u = fmi2_import_get_real_type_unit(rt);
577                                 if(u) result[i].unit = fmi2_import_get_unit_name(u);
578                    }
579           }
580
581     }
582
583         return result;
584
585 }
586
587 int FMI1_CS_INSTANTIATE(void *fmu, const char *instanceName, const char **error) {
588
589         fmi1_string_t fmuLocation;
590         fmi1_string_t mimeType;
591         fmi1_real_t timeout;
592         fmi1_boolean_t visible;
593         fmi1_boolean_t interactive;
594         fmi1_boolean_t loggingOn;
595
596         jm_status_enu_t jmstatus;
597
598         fmuLocation = "";
599         mimeType = "";
600         timeout = 0;
601         visible = fmi1_false;
602         interactive = fmi1_false;
603         loggingOn = fmi1_true;
604
605         jmstatus = fmi1_import_instantiate_slave((fmi1_import_t*)fmu, instanceName, NULL, NULL, timeout, fmi1_false, fmi1_false);
606         if (jmstatus == jm_status_error) {
607                 *error = fmi1_import_get_last_error((fmi1_import_t*)fmu);
608                 return 1;
609         }
610         return 0;
611 }
612
613 int FMI2_CS_INSTANTIATE(void *fmu, const char *instanceName, const char **error) {
614
615         fmi2_string_t fmuLocation;
616         fmi2_string_t mimeType;
617         fmi2_real_t timeout;
618         fmi2_boolean_t visible;
619         fmi2_boolean_t interactive;
620         fmi2_boolean_t loggingOn;
621         jm_status_enu_t jmstatus;
622
623         fmuLocation = "";
624         mimeType = "";
625         timeout = 0;
626         visible = fmi2_false;
627         jmstatus = fmi2_import_instantiate((fmi2_import_t*)fmu, instanceName, fmi2_cosimulation, NULL, visible);
628         if (jmstatus == jm_status_error) {
629                 *error = fmi2_import_get_last_error((fmi2_import_t*)fmu);
630                 return 1;
631         }
632         return 0;
633 }
634
635 int FMI1_CS_INITIALIZE(void *fmu, const char **error) {
636
637         fmi1_status_t status;
638         fmi1_real_t tStart;
639         fmi1_real_t tStop;
640         fmi1_boolean_t StopTimeDefined;
641
642         tStart = 0;
643         tStop = 10;
644         StopTimeDefined = fmi1_false;
645
646         status = fmi1_import_initialize_slave((fmi1_import_t *)fmu, tStart, StopTimeDefined, tStop);
647         if (status == fmi1_status_error || status == fmi1_status_fatal) {
648                 printf("fmi1_capi_initialize_slave:              Failed\n");
649                 return 0;
650         } else {
651                 printf("fmi1_capi_initialize_slave:              Success\n");
652         }
653         return 0;
654
655 }
656
657 int FMI2_CS_INITIALIZE(void *fmu, const char **error) {
658
659         fmi2_real_t tStart;
660         fmi2_real_t tStop;
661         fmi2_boolean_t StopTimeDefined;
662         fmi2_real_t relativeTol = 1e-4;
663
664         fmi2_status_t fmistatus;
665
666         tStart = 0;
667         tStop = 10;
668         StopTimeDefined = fmi1_false;
669
670         fmistatus = fmi2_import_setup_experiment((fmi2_import_t*)fmu, fmi2_true, relativeTol, tStart, StopTimeDefined, tStop);
671     if(fmistatus != fmi2_status_ok) {
672         *error = ("fmi2_import_setup_experiment failed\n");
673                 return 1;
674     }
675
676     fmistatus = fmi2_import_enter_initialization_mode((fmi2_import_t*)fmu);
677     if(fmistatus != fmi2_status_ok) {
678         *error = ("fmi2_import_enter_initialization_mode failed\n");
679                 return 1;
680     }
681
682     fmistatus = fmi2_import_exit_initialization_mode((fmi2_import_t*)fmu);
683     if(fmistatus != fmi2_status_ok) {
684         *error = ("fmi2_import_exit_initialization_mode failed\n");
685                 return 1;
686     }   
687
688         return 0;
689 }
690
691 int FMI1_CS_STEP(void *fmu, double masterTime, double stepSize, const char **error) {
692
693     fmi1_status_t status;
694
695         status = fmi1_import_do_step((fmi1_import_t *)fmu, (fmi1_real_t)masterTime, (fmi1_real_t)stepSize, fmi1_true);
696         if (status == fmi1_status_error || status == fmi1_status_fatal) {
697                 *error = "Error happened during stepping!";
698                 return 1;
699         }
700         return 0;
701 }
702
703 int FMI2_CS_STEP(void *fmu, double masterTime, double stepSize, const char **error) {
704
705     fmi2_status_t status;
706
707         status = fmi2_import_do_step((fmi2_import_t *)fmu, (fmi2_real_t)masterTime, (fmi2_real_t)stepSize, fmi2_true);
708         if (status == fmi2_status_error || status == fmi2_status_fatal) {
709                 *error = "Error happened during stepping!";
710                 return 1;
711         }
712         return 0;
713 }
714
715 int FMI1_CS_SET_REAL(void *fmu, int valueId, double value, const char **error) {
716
717         fmi1_status_t status;
718
719         fmi1_value_reference_t vr = valueId;
720         status = fmi1_import_set_real((fmi1_import_t *)fmu, &vr, 1, &value);
721         if (status == fmi1_status_error || status == fmi1_status_fatal) {
722                 *error = "Error happened during setting real value!";
723                 return 1;
724         }
725         return 0;
726 }
727
728 int FMI2_CS_SET_REAL(void *fmu, int valueId, double value, const char **error) {
729
730         fmi2_status_t status;
731
732         fmi2_value_reference_t vr = valueId;
733         status = fmi2_import_set_real((fmi2_import_t *)fmu, &vr, 1, &value);
734         if (status == fmi2_status_error || status == fmi2_status_fatal) {
735                 *error = "Error happened during setting real value!";
736                 return 1;
737         }
738         return 0;
739 }
740
741 double FMI1_CS_GET_REAL(void *fmu, int valueReference, const char **error) {
742
743         fmi1_value_reference_t vr = valueReference;
744         fmi1_real_t value;
745
746         fmi1_status_t status;
747
748         status = fmi1_import_get_real((fmi1_import_t *)fmu, &vr, 1, &value);
749         if (status == fmi1_status_error || status == fmi1_status_fatal) {
750                 *error = "Error happened during getting real value!";
751         }
752         return value;
753 }
754
755 double FMI2_CS_GET_REAL(void *fmu, int valueReference, const char **error) {
756
757         fmi2_value_reference_t vr = valueReference;
758         fmi2_real_t value;
759
760         fmi2_status_t status;
761
762         status = fmi2_import_get_real((fmi2_import_t *)fmu, &vr, 1, &value);
763         if (status == fmi2_status_error || status == fmi2_status_fatal) {
764                 *error = "Error happened during setting real value!";
765         }
766         return value;
767 }
768
769 int FMI1_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count, const char **error) {
770
771         fmi1_value_reference_t *vrs = (fmi1_value_reference_t*) valueReferences;
772         fmi1_real_t value;
773
774         fmi1_status_t status;
775
776         status = fmi1_import_get_real((fmi1_import_t *)fmu, vrs, count, result);
777         if (status == fmi1_status_error || status == fmi1_status_fatal) {
778                 *error = "Error happened during getting reals value!";
779         }
780         return 0;
781 }
782
783 int FMI2_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count, const char **error) {
784
785         fmi2_value_reference_t *vrs = (fmi2_value_reference_t*) valueReferences;
786         fmi2_real_t value;
787
788         fmi2_status_t status;
789
790         status = fmi2_import_get_real((fmi2_import_t *)fmu, vrs, count, result);
791         if (status == fmi2_status_error || status == fmi2_status_fatal) {
792                 *error = "Error happened during getting reals value!";
793         }
794         return 0;
795
796 }