
/*
 * getSync_Output_Test_OrthOsc2.c C-MEX S-function wrapper.
 *
 *
 * THIS S-FUNCTION IS GENERATED BY jzTc script ".../zbnfjax/Smlk/simulinkSFuncHandle.jzTc" DO NOT MODIFY
 */

/**Must specify the S_FUNCTION_NAME as the name of the S-function.
 */
#define S_FUNCTION_NAME                getSync_Output_Test_OrthOsc2_SfH
#define S_FUNCTION_LEVEL               2

/*
 * Need to include simstruc.h for the definition of the SimStruct and
 * its associated macro definitions.
 */
#include <applstdefJc.h>  //This file is proper defined for the simulink Sfunc environment to define the environment for CRJ 
#include <Fwc/objectBaseC.h>
#undef bool               //it is newly defined in tmwtypes with typedef.
#include "simstruc.h"     //Standard include from mathworks
#include <string.h>  //memset, strcmp
#include <stdlib.h>  //malloc
#include <Fwc/objectBaseC.h>   //The ObjectJc is used as base class for all struct
#include <Jc/reflectionJc.h>   //Access to reflection for bus check necessary
#include <OSAL/os_sharedmem.h> //Support 64-bit-pointer
/*
 * Specific header file(s) required by the S-function.
 */
#include "Output_Test_OrthOsc2.h"


  //Info count parameter and ports from C-routines:
  //Operation-FB   
  //nrofParamsNoTunable = 0, nrofParamsTunable = 0, nrofParams = 0 
  //ixInputStep = 1, nrofInputs = 1, nrofPorts = 6
  //ixOutputThizInit = -1, ixOutputThizStep = -1 
  //ixOutputInit = 0, ixOutputStep = 0, nrofOutputs = 5


/*
 * Code Generation Environment flag (simulation or standalone target).
 */

static int_T isSimulationTarget;

//A static buffer for preparing error messages. 
static char errorbuffer[1024];

#define EDIT_OK(simstruct, P_IDX) \
 (!((ssGetSimMode(simstruct)==SS_SIMMODE_SIZES_CALL_ONLY) && mxIsEmpty(ssGetSFcnParam(simstruct, P_IDX))))
//#define SAMPLE_TIME                    (ssGetSFcnParam(simstruct, 0))
#define isDWorkNeeded(simstruct)               ((!((ssRTWGenIsCodeGen(simstruct) || ssGetSimMode(simstruct)==SS_SIMMODE_EXTERNAL) && isSimulationTarget==0)) || ssIsRapidAcceleratorActive(simstruct))

/*
 * Utility function prototypes.
 */
//static bool IsRealMatrix(const mxArray *m);
static void CheckDataTypes(SimStruct *simstruct);
static int_T GetRTWEnvironmentMode(SimStruct *simstruct);



//should be comment?


//If set, this is the found step time from Global Workspace Tinit.
static double Tinit = 0;  //This value is set from a global Workspace variable with name 'Tinit'. It should be existing.

static int nrofInputPorts =0, nrofOutputPorts =0, nrofParams =0;

//
//The Tstep and Tstep_offset will be set either from parameter Tstep or Tstep_offset in mdlInitializeSizes(...)
//Or it will be set in mdlSetInputPortSampleTime(...) from the environment model.
//If the parameters are given, the input port gets the sample time of the parameter.
//If the parameters are not given, firstly the ports are initialized with INHERITED_SAMPLE_TIME, 
//then the sample time from the model is associated. The sample time of all inherit ports should be the same. 
//
static double TstepG = INHERITED_SAMPLE_TIME;


//struct to return the info to an indexed port.
typedef struct SmlkPortInfo_t {  DTypeId type; ssComplexity complexity; int arraySize; } SmlkPortInfo;








/* Function: mdlInitializeSizes ===========================================
 * Abstract:
 *    The sizes information is used by Simulink to determine the S-function
 *    block's characteristics (number of inputs, outputs, states, etc.).
 */
static void mdlInitializeSizes(SimStruct *simstruct)
{

  
  /*
   * Get the value returned by rtwenvironmentmode(modelName)
   */
  if (ssRTWGenIsCodeGen(simstruct) || ssGetSimMode(simstruct)==SS_SIMMODE_EXTERNAL) {
    isSimulationTarget = GetRTWEnvironmentMode(simstruct);
    if (isSimulationTarget==-1) {
      ssSetErrorStatus(simstruct,
                       "Unable to determine a valid code generation environment mode.");
      return;
    }

    isSimulationTarget |= ssRTWGenIsModelReferenceSimTarget(simstruct);
  }

  
  
  ssSetNumSFcnParams(simstruct, 0);  //no Parameters, no ctor

#if defined(MATLAB_MEX_FILE)

  if (ssGetNumSFcnParams(simstruct) == ssGetSFcnParamsCount(simstruct)) {
    /*
     * If the number of expected input parameters is not equal
     * to the number of parameters entered in the dialog box return.
     * Simulink will generate an error indicating that there is a
     * parameter mismatch.
     */
    //TODO necessary?
    //mdlCheckParameters(simstruct);
    if (ssGetErrorStatus(simstruct) != NULL) {
      return;
    }
  } else {
    /* Return if number of expected != number of actual parameters */
    return;
  }

#endif

  ssSetNumPWork(simstruct, 0);
  
  
  
  //This should be set true, because all FBs can be used as multiple instances.
  ssSupportsMultipleExecInstances(simstruct, true);



  double TstepG = INHERITED_SAMPLE_TIME;   
  
  
  
  /*
   * Set the number of input ports.
   */
   
  if (!ssSetNumInputPorts(simstruct, 1))
    return;
  
  /*
   * Configure the input port 0   jzcmd: initPorts()-A
   */

  ssSetInputPortDataType(simstruct, 0, SS_UINT32);  //input port thiz, it is a handle as reference
  ssSetInputPortWidth(simstruct, 0, 1);
  ssSetInputPortComplexSignal(simstruct, 0, COMPLEX_NO);

  //jzcmd: initPorts()-C
  ssSetInputPortSampleTime(simstruct, 0, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
  ssSetInputPortOffsetTime(simstruct, 0, 0);
  ssSetInputPortDirectFeedThrough(simstruct, 0, 1);
  ssSetInputPortAcceptExprInRTW(simstruct, 0, 1);
  ssSetInputPortOverWritable(simstruct, 0, 1);
  ssSetInputPortOptimOpts(simstruct, 0, SS_REUSABLE_AND_GLOBAL);
  ssSetInputPortRequiredContiguous(simstruct, 0, 1);

  nrofInputPorts = 1;

  /*
   * Set the number of output ports.
   */
   
  if (!ssSetNumOutputPorts(simstruct, 5))
    return;
  nrofOutputPorts = 5;

  //Configure the output port 0  jzcmd: initPorts()-D

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_YES;
    info.arraySize = 2;
    ssSetOutputPortDataType(simstruct, 0, info.type);  //output float_complex pq1_y  //jzTc-initPorts-outputNonBus
    ssSetOutputPortSampleTime(simstruct, 0, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
    ssSetOutputPortOffsetTime(simstruct, 0, 0);
    ssSetOutputPortWidth(simstruct, 0, info.arraySize);
    ssSetOutputPortComplexSignal(simstruct, 0, info.complexity);
    ssSetOutputPortOutputExprInRTW(simstruct, 0, 1);
    ssSetOutputPortOptimOpts(simstruct, 0, SS_REUSABLE_AND_GLOBAL);
  }

  //Configure the output port 1  jzcmd: initPorts()-D

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_NO;
    info.arraySize = 2;
    ssSetOutputPortDataType(simstruct, 1, info.type);  //output float m0_y  //jzTc-initPorts-outputNonBus
    ssSetOutputPortSampleTime(simstruct, 1, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
    ssSetOutputPortOffsetTime(simstruct, 1, 0);
    ssSetOutputPortWidth(simstruct, 1, info.arraySize);
    ssSetOutputPortComplexSignal(simstruct, 1, info.complexity);
    ssSetOutputPortOutputExprInRTW(simstruct, 1, 1);
    ssSetOutputPortOptimOpts(simstruct, 1, SS_REUSABLE_AND_GLOBAL);
  }

  //Configure the output port 2  jzcmd: initPorts()-D

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_NO;
    info.arraySize = 2;
    ssSetOutputPortDataType(simstruct, 2, info.type);  //output float m1_y  //jzTc-initPorts-outputNonBus
    ssSetOutputPortSampleTime(simstruct, 2, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
    ssSetOutputPortOffsetTime(simstruct, 2, 0);
    ssSetOutputPortWidth(simstruct, 2, info.arraySize);
    ssSetOutputPortComplexSignal(simstruct, 2, info.complexity);
    ssSetOutputPortOutputExprInRTW(simstruct, 2, 1);
    ssSetOutputPortOptimOpts(simstruct, 2, SS_REUSABLE_AND_GLOBAL);
  }

  //Configure the output port 3  jzcmd: initPorts()-D

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_NO;
    info.arraySize = 2;
    ssSetOutputPortDataType(simstruct, 3, info.type);  //output float m2_y  //jzTc-initPorts-outputNonBus
    ssSetOutputPortSampleTime(simstruct, 3, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
    ssSetOutputPortOffsetTime(simstruct, 3, 0);
    ssSetOutputPortWidth(simstruct, 3, info.arraySize);
    ssSetOutputPortComplexSignal(simstruct, 3, info.complexity);
    ssSetOutputPortOutputExprInRTW(simstruct, 3, 1);
    ssSetOutputPortOptimOpts(simstruct, 3, SS_REUSABLE_AND_GLOBAL);
  }

  //Configure the output port 4  jzcmd: initPorts()-D

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_NO;
    info.arraySize = 2;
    ssSetOutputPortDataType(simstruct, 4, info.type);  //output float m3_y  //jzTc-initPorts-outputNonBus
    ssSetOutputPortSampleTime(simstruct, 4, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
    ssSetOutputPortOffsetTime(simstruct, 4, 0);
    ssSetOutputPortWidth(simstruct, 4, info.arraySize);
    ssSetOutputPortComplexSignal(simstruct, 4, info.complexity);
    ssSetOutputPortOutputExprInRTW(simstruct, 4, 1);
    ssSetOutputPortOptimOpts(simstruct, 4, SS_REUSABLE_AND_GLOBAL);
  }


  /*
   * Register reserved identifiers to avoid name conflict
   */
  if (ssRTWGenIsCodeGen(simstruct) || ssGetSimMode(simstruct)==SS_SIMMODE_EXTERNAL) {
    /*
     * Register reserved identifier for InitializeConditionsFcnSpec
     */
    //it seems to be not necessary, the S-functions works proper.
    //ssRegMdlInfo(simstruct, "ctor_Orthi_FB", MDL_INFO_ID_RESERVED, 0, 0, ssGetPath(simstruct));
  }

  /*
   * This S-function can be used in referenced model simulating in normal mode.
   */
  ssSetModelReferenceNormalModeSupport(simstruct, MDL_START_AND_MDL_PROCESS_PARAMS_OK);

  //The sample times should be port based. The handle ports are associated to TstepG because execution order. 
  //
  
  ssSetNumSampleTimes(simstruct, 1);  //Operation-FB TstepG may be given as parameter or the FB is inherited.
  
  /*
   * Set the compliance with the SimState feature.
   */
  ssSetSimStateCompliance(simstruct, USE_DEFAULT_SIM_STATE);

  /*
   * All options have the form SS_OPTION_<name> and are documented in                
   * matlabroot/simulink/include/simstruc.h. The options should be
   * bitwise or'd together as in
   *   ssSetOptions(simstruct, (SS_OPTION_name1 | SS_OPTION_name2))
   */
  ssSetOptions( simstruct,
                SS_OPTION_USE_TLC_WITH_ACCELERATOR |
                SS_OPTION_CAN_BE_CALLED_CONDITIONALLY |
                SS_OPTION_EXCEPTION_FREE_CODE |
                SS_OPTION_WORKS_WITH_CODE_REUSE |
                SS_OPTION_SFUNCTION_INLINED_FOR_RTW |
                SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME
                
              );

#if defined(MATLAB_MEX_FILE)

  if ((ssGetSimMode(simstruct)!=SS_SIMMODE_SIZES_CALL_ONLY) && !ssRTWGenIsCodeGen(simstruct)) {
    /* Verify Data Type consistency with specification */
    CheckDataTypes(simstruct);
  }

#endif

  //TODO necessary ? ssSetSimulinkVersionGeneratedIn(simstruct, "8.7");
}



//
//Set sample time of ports with INHERITED_SAMPLE_TIME.
//It determines the step sample time.
//This routine is invoked only if PORT_BASED_SAMPLE_TIMES are set. It may be need as information for multiple rate blocks too.
//
#define MDL_SET_INPUT_PORT_SAMPLE_TIME 
//This method is used to determine the sample time of that input ports they were set to INHERITED_SAMPLE_TIME
void mdlSetInputPortSampleTime(SimStruct *simstruct, int_T port, real_T sampleTime, real_T offsetTime)
{ int ix;
  TstepG = sampleTime;
  ssSetInputPortSampleTime(simstruct, port, sampleTime);
  ssSetInputPortOffsetTime(simstruct, port, offsetTime);
  //the first invocation sets all other. Ports can be disconnected. Only one inherited sample time.
  for(ix = 0; ix < 1; ++ix) {
    if(ssGetInputPortSampleTime(simstruct, ix) == INHERITED_SAMPLE_TIME) {
      ssSetInputPortSampleTime(simstruct, ix, sampleTime);
      ssSetInputPortOffsetTime(simstruct, ix, offsetTime);
    }
  }
  for(ix = 0; ix < 5; ++ix) {
    if(ssGetOutputPortSampleTime(simstruct, ix) == INHERITED_SAMPLE_TIME) {
      ssSetOutputPortSampleTime(simstruct, ix, sampleTime);
      ssSetOutputPortOffsetTime(simstruct, ix, offsetTime);
    }
  }
}


#define MDL_SET_OUTPUT_PORT_SAMPLE_TIME
//This method is used to determine the sample time of that output ports they were set to INHERITED_SAMPLE_TIME
void mdlSetOutputPortSampleTime(SimStruct *simstruct, int_T port, real_T sampleTime, real_T offsetTime)
{
  ssSetOutputPortSampleTime(simstruct, port, sampleTime);
  ssSetOutputPortOffsetTime(simstruct, port, offsetTime);
}












#define MDL_INITIALIZE_SAMPLE_TIMES
/* Function: mdlInitializeSampleTimes =====================================
 * Abstract:
 *    This function is used to specify the sample time(s) for your
 *    S-function. You must register the same number of sample times as
 *    specified in ssSetNumSampleTimes.
 */
static void mdlInitializeSampleTimes(SimStruct *simstruct)
{
  int ix;
  //Check all input ports whether there sample time is known.
  //Note: the sample time is not known in test, whats happen?
  //Only test:
  for(ix = 0; ix < nrofInputPorts; ++ix) {
    double time = ssGetInputPortSampleTime(simstruct, ix);
    if(time == Tinit){ }
    else if(TstepG == -1) { TstepG = time; }
    else if(time != TstepG) {
      //a second time, warning
    }
    else {} //time is known already.
  }
  
    //does not work: if  ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES) in mdlInitializeSizes(...)
    //               it cannot be changed postum here to not portbased
    //                   Tinit + Tstep
    //ssSetNumSampleTimes(simstruct, false + true);  //that requires mdlInitializeSampleTimes(...)
      
      //Tstep may be set to INHERITED_SAMPLE_TIME = -1 initially.
      if(TstepG >0) { //given
        ssSetSampleTime(simstruct, 0, TstepG) ;
        ssSetOffsetTime(simstruct, 0, 0) ;  //FIXED_IN_MINOR_STEP_OFFSET) ;
      } else {
        //Only one sample time. then INHERITED_SAMPLE_TIME is accepted:
        ssSetSampleTime(simstruct, 0, INHERITED_SAMPLE_TIME) ;
        ssSetOffsetTime(simstruct, 0, 0) ;
      }
     
#if defined(ssSetModelReferenceSampleTimeDefaultInheritance)

  ssSetModelReferenceSampleTimeDefaultInheritance(simstruct);

#endif

}







#define MDL_SET_WORK_WIDTHS
#if defined(MDL_SET_WORK_WIDTHS) && defined(MATLAB_MEX_FILE)

/* Function: mdlSetWorkWidths =============================================
 * Abstract:
 *      The optional method, mdlSetWorkWidths is called after input port
 *      width, output port width, and sample times of the S-function have
 *      been determined to set any state and work vector sizes which are
 *      a function of the input, output, and/or sample times.
 *
 *      Run-time parameters are registered in this method using methods
 *      ssSetNumRunTimeParams, ssSetRunTimeParamInfo, and related methods.
 */
static void mdlSetWorkWidths(SimStruct *simstruct)
{
  

  ssSupportsMultipleExecInstances(simstruct, true);
}

#endif


#include <Fwc/fw_handle_ptr64.h>



#define MDL_START
#if defined(MDL_START)

/* Function: mdlStart =====================================================
 * Abstract:
 *    This function is called once at start of model execution. If you
 *    have states that should be initialized once, this is the place
 *    to do it.
 */
static void mdlStart(SimStruct *simstruct)
{
  if (isDWorkNeeded(simstruct)) {
    //
    //===============Get the address of the structure to convert handle values to pointer===============================
    //Note: If more as one instance of this FB will be created, the mdlStart is invoked for any instance.
    //      But there is only one static shMemHandle2Ptr. The first mdlStart creates it. Don't call twice!
    //       
    //
    char const* error = init_Handle2Ptr(1000);
    if(error !=null) {
      ssSetErrorStatus(simstruct, error); // Sfunc=getSync_Output_Test_OrthOsc2");
      return;
    }
    
    
    //
    

  }
}

#endif











#define MDL_INITIALIZE_CONDITIONS
#if defined(MDL_INITIALIZE_CONDITIONS)

/* Function: mdlInitializeConditions ======================================
 * Abstract:
 *    In this function, you should initialize the states for your S-function block.
 *    You can also perform any other initialization activities that your
 *    S-function may require. Note, this routine will be called at the
 *    start of simulation and if it is present in an enabled subsystem
 *    configured to reset states, it will be call when the enabled subsystem
 *    restarts execution to reset the states.
 */
static void mdlInitializeConditions(SimStruct *simstruct)
{
  if (isDWorkNeeded(simstruct)) {
    
  }
}

#endif













/* Function: mdlUpdate ===================================================*/
//not used not necessary.
#define MDL_UPDATE 
#if defined(MDL_UPDATE) && defined(MATLAB_MEX_FILE) 
static void mdlUpdate(SimStruct *simstruct, int_T tid)
{ if (isDWorkNeeded(simstruct)) {
    tid +=1;  //nop, for break point.
  }
}
#endif





/* Function: mdlOutputs ===================================================
 * Abstract:
 *    In this function, you compute the outputs of your S-function
 *    block. Generally outputs are placed in the output vector(s),
 *    ssGetOutputPortSignal.
 */
#define MDL_OUTPUT 
static void mdlOutputs(SimStruct *simstruct, int_T tid)
{ if (isDWorkNeeded(simstruct)) {
    
    //Operation-FB:  
    //nrof params = 0,  nrof input ports = 1, nrof output ports = 5  

    char const* error = null;

          uint32 thiz_Handle = *(uint32*)ssGetInputPortSignal(simstruct, 0);  //input-handle
           Output_Test_OrthOsc2* thiz_Ptr;  //
           Output_Test_OrthOsc2* thiz;  //

          if(thiz_Handle == 0) {
            return;  //not initialized yet, only on startup.
          }
          error = getPtr_Handle2Ptr(thiz_Handle, (void**)(&(thiz_Ptr)));
          if(error) { 
            ssSetErrorStatus(simstruct, "Handle faulty, abort: Sfunc=getSync_Output_Test_OrthOsc2: thiz");
            return;
          }
          if(thiz_Ptr != null) {
            //don't check if null, null is admissable, it is returned from getPtr_Handle2Ptr(...) if handle == -1
            //A handle input should based on ObjectJc in any case. To prevent errors on faulty handle values, check whether the ObjectJc is correct. 
            if( -1 == checkStrict_ObjectJc((ObjectJc*)(thiz_Ptr), /*sizeof(Output_Test_OrthOsc2)*/0, 0, null, null)) {
              ssSetErrorStatus(simstruct,"faulty ObjectJc-reference: Sfunc=getSync_Output_Test_OrthOsc2: thiz");
              return;
            }
            { 
              //char const* reflType = ((ObjectJc*)(thiz_Ptr))->reflectionClass->name;
              //if( strcmp(reflType,"Output_Test_OrthOsc2") !=0 && strcmp("void", "Output_Test_OrthOsc2") !=0) {  //void accepts any type based on ObjectJc
              if(!instanceof_s_ObjectJc((ObjectJc*)(thiz_Ptr), "Output_Test_OrthOsc2")) {
                ssSetErrorStatus(simstruct,"faulty reference type: expected: Output_Test_OrthOsc2, Sfunc=getSync_Output_Test_OrthOsc2: thiz ");
                return;
          } } }
          //

          thiz = thiz_Ptr;      

    //jzcmd: genStepMethod()-B
    float_complex * pq1_y = (float_complex *)ssGetOutputPortSignal(simstruct, 0);  //gets the address of the output data in Simulink data area.

    //jzcmd: genStepMethod()-B
    float * m0_y = (float *)ssGetOutputPortSignal(simstruct, 1);  //gets the address of the output data in Simulink data area.

    //jzcmd: genStepMethod()-B
    float * m1_y = (float *)ssGetOutputPortSignal(simstruct, 2);  //gets the address of the output data in Simulink data area.

    //jzcmd: genStepMethod()-B
    float * m2_y = (float *)ssGetOutputPortSignal(simstruct, 3);  //gets the address of the output data in Simulink data area.

    //jzcmd: genStepMethod()-B
    float * m3_y = (float *)ssGetOutputPortSignal(simstruct, 4);  //gets the address of the output data in Simulink data area.

    //Sampletimes used: Tinit = false  Tstep = true

    time_T time_SmlkStep_ = ssGetT(simstruct);
    if(isInitialized_ObjectJc((ObjectJc*)thiz)) { //JzTc: only Tstep    
        //invoke the step-routine: jzTc: genStepMethod()-E
        getSync_Output_Test_OrthOsc2(thiz, pq1_y, m0_y, m1_y, m2_y, m3_y);

    }

  }
}










    
/* Function: mdlTerminate =================================================
 * Abstract:
 *    In this function, you should perform any actions that are necessary
 *    at the termination of a simulation.
 */
static void mdlTerminate(SimStruct *simstruct)
{
  if (isDWorkNeeded(simstruct)) {
    
  //close the sharedmem handle:
  //Note: If more as one instance of this FB was created, the mdlTerminate is invoked for any instance.
  //      But there is only one static shMemHandle2Ptr. The first mdlTerminate removes it.
  //       
  close_Hande2Ptr();

  }
}







#define MDL_RTW
#if defined(MATLAB_MEX_FILE) && defined(MDL_RTW)

/* Function: mdlRTW =======================================================
 * Abstract:
 *    This function is called when Simulink Coder is generating
 *    the model.rtw file.
 */
static void mdlRTW(SimStruct *simstruct)
{ 
}

#endif


/* Function: CheckDataTypeChecksum ======================================
 * Abstract:
 *    CheckDataTypeChecksum invokes a MATLAB helper for checking the consistency
 *    between the data type definition used when this S-Function was generated
 *    and the data type used when calling the S-Function.
 */
static int_T CheckDataTypeChecksum(SimStruct *simstruct, const char* dtypeName, uint32_T*
  chkRef)
{
  mxArray *plhs[1] = { NULL };

  mxArray *prhs[3];
  mxArray *err = NULL;
  const char *bpath = ssGetPath(simstruct);
  int_T status = -1;
  prhs[0] = mxCreateString(bpath);
  prhs[1] = mxCreateString(dtypeName);
  prhs[2] = mxCreateDoubleMatrix(1, 4, mxREAL);
  mxGetPr(prhs[2])[0] = chkRef[0];
  mxGetPr(prhs[2])[1] = chkRef[1];
  mxGetPr(prhs[2])[2] = chkRef[2];
  mxGetPr(prhs[2])[3] = chkRef[3];
  err = mexCallMATLABWithTrap(1, plhs, 3, prhs,
    "legacycode.LCT.getOrCompareDataTypeChecksum");
  mxDestroyArray(prhs[0]);
  mxDestroyArray(prhs[1]);
  mxDestroyArray(prhs[2]);
  if (err==NULL && plhs[0]!=NULL) {
    status = mxIsEmpty(plhs[0]) ? -1 : (int_T) (mxGetScalar(plhs[0]) != 0);
    mxDestroyArray(plhs[0]);
  }

  return status;
}













/* Function: CheckDataTypes =============================================
 * Abstract:
 *    CheckDataTypes verifies data type consistency between the data type
 *    definition used when this S-Function was generated and the data type
 *    used when calling the S-Function.
 */
static void CheckDataTypes(SimStruct *simstruct)
{
 
  //TODO check with known bus element names and their types.
  //from where is the check sum?
  /* Verify Bus/StructType 'Param_Orthi_FB', specification * /
  {
    uint32_T chk[] = { 4189326214, 1854717099, 3653914067, 1841847726 };

    int_T status;
    status = CheckDataTypeChecksum(simstruct, "Param_Orthi_FB", &chk[0]);
    if (status==-1) {
      ssSetErrorStatus(simstruct,
                       "Unexpected error when checking the validity of the Simulink Bus/StructType 'Param_Orthi_FB'");
    } else if (status==0) {
      ssSetErrorStatus(simstruct,
                       "The Simulink Bus/StructType 'Param_Orthi_FB' definition has changed since the S-Function was generated");
    }
  }
  TODO */
}











/* Function: GetRTWEnvironmentMode ======================================
 * Abstract:
 *    Must be called when ssRTWGenIsCodeGen(simstruct)==true. This function
 *    returns the code generation mode:
 *      -1 if an error occurred
 *       0 for standalone code generation target
 *       1 for simulation target (Accelerator, RTW-SFcn,...)
 */
static int_T GetRTWEnvironmentMode(SimStruct *simstruct)
{
  int_T status;
  mxArray *plhs[1];
  mxArray *prhs[1];
  int_T err;

  /*
   * Get the name of the Simulink block diagram
   */
  prhs[0] = mxCreateString(ssGetModelName(ssGetRootSS(simstruct)));
  plhs[0] = NULL;

  /*
   * Call "isSimulationTarget = rtwenvironmentmode(modelName)" in MATLAB
   */
  mexSetTrapFlag(1);
  err = mexCallMATLAB(1, plhs, 1, prhs, "rtwenvironmentmode");
  mexSetTrapFlag(0);
  mxDestroyArray(prhs[0]);

  /*
   * Set the error status if an error occurred
   */
  if (err) {
    if (plhs[0]) {
      mxDestroyArray(plhs[0]);
      plhs[0] = NULL;
    }

    ssSetErrorStatus(simstruct, "Unknown error during call to 'rtwenvironmentmode'.");
    return -1;
  }

  /*
   * Get the value returned by rtwenvironmentmode(modelName)
   */
  if (plhs[0]) {
    status = (int_T) (mxGetScalar(plhs[0]) != 0);
    mxDestroyArray(plhs[0]);
    plhs[0] = NULL;
  }

  return (status);
}

/*
 * Required S-function trailer
 */
#ifdef MATLAB_MEX_FILE
# include "simulink.c"
#else
# include "cg_sfun.h"
#endif

