
/*
 * set_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                set_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:
  //Object-FB   
  //nrofParamsNoTunable = 1, nrofParamsTunable = 0, nrofParams = 1 
  //ixInputStep = 0, nrofInputs = 6, nrofPorts = 8
  //ixOutputThizInit = 0, ixOutputThizStep = 1 
  //ixOutputInit = 2, ixOutputStep = 2, nrofOutputs = 2


/*
 * 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);


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

/* Function: mdlCheckParameters ===========================================
 * Abstract:
 *    mdlCheckParameters verifies new parameter settings whenever parameter
 *    change or are re-evaluated during a simulation. When a simulation is
 *    running, changes to S-function parameters can occur at any time during
 *    the simulation loop.
 */
static void mdlCheckParameters(SimStruct *simstruct)
{

  if EDIT_OK(simstruct, 0) {
    int_T dimsArray[1] = { 1};
  
    /* Check the parameter attributes */
    //TODO ? ssCheckSFcnParamValueAttribs(simstruct, 0, "identObj", SS_INT32, 0, dimsArray, 0);  //int32
  }
  
}

#endif




                                                             


//#define MDL_PROCESS_PARAMETERS
#if defined(MDL_PROCESS_PARAMETERS) && defined(MATLAB_MEX_FILE)

/* Function: mdlProcessParameters =========================================
 * Abstract:
 *    Update run-time parameters.
 */
static void XXXmdlProcessParameters(SimStruct *simstruct)
{
  /* Update Run-Time parameters */
  //ssUpdateAllTunableParamsAsRunTimeParams(simstruct);
}

#endif


//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);
  }

  
  
  /* Number of expected parameters */
  ssSetNumSFcnParams(simstruct, 1);
  #if defined(MATLAB_MEX_FILE)

  if (ssGetSFcnParamsCount(simstruct) == 1) {
    /*
     * 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.
     */
    mdlCheckParameters(simstruct);
    if (ssGetErrorStatus(simstruct) != NULL) {
      return;
    }
  } else {
    /* Return if number of expected != number of actual parameters */
    return;
  }

  #endif
  ssSetSFcnParamTunable(simstruct, 0, 0);  //ctor identObj 

#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);
  
  
  //Dwork is needed
  if (!ssSetNumDWork(simstruct, 2))  //3 Dwork Pointer, 0 for Bus indices, 1 for thiz handle, 2 for thiz 
    return;

  /*
   * Configure the dwork 0, 2 (thiz)
   */
  ssSetDWorkDataType(simstruct, 0, SS_UINT32);  //for handle thiz
  ssSetDWorkUsageType(simstruct, 0, SS_DWORK_USED_AS_DWORK);
  ssSetDWorkName(simstruct, 0, "thiz_h");
  ssSetDWorkWidth(simstruct, 0, 1);   
  ssSetDWorkComplexSignal(simstruct, 0, COMPLEX_NO);

  //dwork for the allocated thiz
  ssSetDWorkDataType(simstruct, 1, SS_POINTER);  //for thiz itself.
  ssSetDWorkUsageType(simstruct, 1, SS_DWORK_USED_AS_DWORK);
  ssSetDWorkName(simstruct, 1, "thiz");
  ssSetDWorkWidth(simstruct, 1, 1);   
  ssSetDWorkComplexSignal(simstruct, 1, COMPLEX_NO);
  

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



  double TstepG = INHERITED_SAMPLE_TIME;   
  
  
  
  if(Tinit == 0) { //only 1 time.      
    //Gets the value of the Tinit time from the global workspace variable Tinit.
    int error;
    mxArray* args[2];
    mxArray* out;
    args[0] = mxCreateString("base");
    args[1] = mxCreateString("Tinit");
    error = mexCallMATLAB(1, &out, 2, args, "evalin"); //eval in workspace base
    if(error ==0) { //Tinit found:
      Tinit = *mxGetPr(out);   //gets the double result 
    } else  {
      Tinit = 0.1;  //default value
      ssSetErrorStatus(simstruct,"In set_Output_Test_OrthOsc2.: The workspace should contain a variable 'Tinit' with a real value.");
      return;
    }
  }

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

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_YES;
    info.arraySize = 2;
    ssSetInputPortDataType(simstruct, 0, info.type); //input port pq1
    ssSetInputPortWidth(simstruct, 0, info.arraySize);
    ssSetInputPortComplexSignal(simstruct, 0, info.complexity);
  }
  //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);

  /*
   * Configure the input port 1   jzcmd: initPorts()-A
   */

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_NO;
    info.arraySize = 2;
    ssSetInputPortDataType(simstruct, 1, info.type); //input port m0
    ssSetInputPortWidth(simstruct, 1, info.arraySize);
    ssSetInputPortComplexSignal(simstruct, 1, info.complexity);
  }
  //jzcmd: initPorts()-C
  ssSetInputPortSampleTime(simstruct, 1, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
  ssSetInputPortOffsetTime(simstruct, 1, 0);
  ssSetInputPortDirectFeedThrough(simstruct, 1, 1);
  ssSetInputPortAcceptExprInRTW(simstruct, 1, 1);
  ssSetInputPortOverWritable(simstruct, 1, 1);
  ssSetInputPortOptimOpts(simstruct, 1, SS_REUSABLE_AND_GLOBAL);
  ssSetInputPortRequiredContiguous(simstruct, 1, 1);

  /*
   * Configure the input port 2   jzcmd: initPorts()-A
   */

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_NO;
    info.arraySize = 2;
    ssSetInputPortDataType(simstruct, 2, info.type); //input port m1
    ssSetInputPortWidth(simstruct, 2, info.arraySize);
    ssSetInputPortComplexSignal(simstruct, 2, info.complexity);
  }
  //jzcmd: initPorts()-C
  ssSetInputPortSampleTime(simstruct, 2, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
  ssSetInputPortOffsetTime(simstruct, 2, 0);
  ssSetInputPortDirectFeedThrough(simstruct, 2, 1);
  ssSetInputPortAcceptExprInRTW(simstruct, 2, 1);
  ssSetInputPortOverWritable(simstruct, 2, 1);
  ssSetInputPortOptimOpts(simstruct, 2, SS_REUSABLE_AND_GLOBAL);
  ssSetInputPortRequiredContiguous(simstruct, 2, 1);

  /*
   * Configure the input port 3   jzcmd: initPorts()-A
   */

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_NO;
    info.arraySize = 2;
    ssSetInputPortDataType(simstruct, 3, info.type); //input port m2
    ssSetInputPortWidth(simstruct, 3, info.arraySize);
    ssSetInputPortComplexSignal(simstruct, 3, info.complexity);
  }
  //jzcmd: initPorts()-C
  ssSetInputPortSampleTime(simstruct, 3, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
  ssSetInputPortOffsetTime(simstruct, 3, 0);
  ssSetInputPortDirectFeedThrough(simstruct, 3, 1);
  ssSetInputPortAcceptExprInRTW(simstruct, 3, 1);
  ssSetInputPortOverWritable(simstruct, 3, 1);
  ssSetInputPortOptimOpts(simstruct, 3, SS_REUSABLE_AND_GLOBAL);
  ssSetInputPortRequiredContiguous(simstruct, 3, 1);

  /*
   * Configure the input port 4   jzcmd: initPorts()-A
   */

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_NO;
    info.arraySize = 2;
    ssSetInputPortDataType(simstruct, 4, info.type); //input port m3
    ssSetInputPortWidth(simstruct, 4, info.arraySize);
    ssSetInputPortComplexSignal(simstruct, 4, info.complexity);
  }
  //jzcmd: initPorts()-C
  ssSetInputPortSampleTime(simstruct, 4, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
  ssSetInputPortOffsetTime(simstruct, 4, 0);
  ssSetInputPortDirectFeedThrough(simstruct, 4, 1);
  ssSetInputPortAcceptExprInRTW(simstruct, 4, 1);
  ssSetInputPortOverWritable(simstruct, 4, 1);
  ssSetInputPortOptimOpts(simstruct, 4, SS_REUSABLE_AND_GLOBAL);
  ssSetInputPortRequiredContiguous(simstruct, 4, 1);

  /*
   * Configure the input port 5   jzcmd: initPorts()-A
   */

  { SmlkPortInfo info;
    info.type = SS_SINGLE;
    info.complexity = COMPLEX_NO;
    info.arraySize = 2;
    ssSetInputPortDataType(simstruct, 5, info.type); //input port e
    ssSetInputPortWidth(simstruct, 5, info.arraySize);
    ssSetInputPortComplexSignal(simstruct, 5, info.complexity);
  }
  //jzcmd: initPorts()-C
  ssSetInputPortSampleTime(simstruct, 5, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
  ssSetInputPortOffsetTime(simstruct, 5, 0);
  ssSetInputPortDirectFeedThrough(simstruct, 5, 1);
  ssSetInputPortAcceptExprInRTW(simstruct, 5, 1);
  ssSetInputPortOverWritable(simstruct, 5, 1);
  ssSetInputPortOptimOpts(simstruct, 5, SS_REUSABLE_AND_GLOBAL);
  ssSetInputPortRequiredContiguous(simstruct, 5, 1);

  nrofInputPorts = 6;

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

  ssSetOutputPortDataType(simstruct, 0, SS_UINT32);  //output    //jzTc-initPorts-outputNonBus
  ssSetOutputPortSampleTime(simstruct, 0, Tinit);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
  ssSetOutputPortOffsetTime(simstruct, 0, 0);
  ssSetOutputPortWidth(simstruct, 0, 1);
  ssSetOutputPortComplexSignal(simstruct, 0, COMPLEX_NO);
  ssSetOutputPortOutputExprInRTW(simstruct, 0, 1);
  ssSetOutputPortOptimOpts(simstruct, 0, SS_REUSABLE_AND_GLOBAL);

  ssSetOutputPortDataType(simstruct, 1, SS_UINT32);  //output    //jzTc-initPorts-outputNonBus
  ssSetOutputPortSampleTime(simstruct, 1, TstepG);   //together with ssSetNumSampleTimes(simstruct, PORT_BASED_SAMPLE_TIMES)
  ssSetOutputPortOffsetTime(simstruct, 1, 0);                                                                 
  ssSetOutputPortWidth(simstruct, 1, 1);
  ssSetOutputPortComplexSignal(simstruct, 1, COMPLEX_NO);
  ssSetOutputPortOutputExprInRTW(simstruct, 1, 1);
  ssSetOutputPortOptimOpts(simstruct, 1, 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, PORT_BASED_SAMPLE_TIMES); //maybe TstepG is given, if no input ports.
  
  /*
   * 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
                | SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED
              );

#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 < 6; ++ix) {
    if(ssGetInputPortSampleTime(simstruct, ix) == INHERITED_SAMPLE_TIME) {
      ssSetInputPortSampleTime(simstruct, ix, sampleTime);
      ssSetInputPortOffsetTime(simstruct, ix, offsetTime);
    }
  }
  for(ix = 0; ix < 2; ++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.
  }
   
#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)
{
  
  //======= Number of runtime parameters ==============================================
  //NOTE SFunc: This is the necessary operation to support ssGetRunTimeParamInfo(...)
  if (!ssSetNumRunTimeParams(simstruct, 0))
    return;
  

  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=set_Output_Test_OrthOsc2");
      return;
    }
    
    
    //
    
  { //Allocates the memory for the bus data for the C-function.
    //The bus data are allocated for this instance especially. 
    //jzcmd: setBusInfo_mdlStart()-A
    char const* error;
    uint32 handle;
    int size1 = (int)sizeof(Output_Test_OrthOsc2);
    ObjectJc* ptr = (ObjectJc*)calloc(size1+1024, 1);
    if (ptr==NULL) {
      ssSetErrorStatus(simstruct,"Unexpected error during the memory allocation for Output_Test_OrthOsc2");
      return;
    }
    init_ObjectJc(ptr, size1, ident_newAllocated_ObjectJc);
    void** addr_ptr = (void**) ssGetDWork(simstruct, 1);  //there is only one DWork, for thiz or thiz_y
    if(addr_ptr !=null) {
      *addr_ptr = ptr;
    } else {
      ssSetErrorStatus(simstruct,"DWork(2) not existent:  ctor_Output_Test_OrthOsc2");
    }
    error = registerPtr_Handle2Ptr(ptr, "ctor_Output_Test_OrthOsc2", &handle);
    if(error !=null) {
      ssSetErrorStatus(simstruct,error);
      return;
    }
    uint32* addr_handle = (uint32*) ssGetDWork(simstruct, 0);  //there is only one DWork, for thiz or thiz_y
    if(addr_handle !=null) {
      *addr_handle = handle;
    } else {
      ssSetErrorStatus(simstruct,"DWork(1) not existent:  ctor_Output_Test_OrthOsc2");
    }
    //
  }


  }
}

#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)) {
    
    //jzTc-ctor-arg thiz:
    Output_Test_OrthOsc2** addr_thiz = (Output_Test_OrthOsc2**)ssGetDWork(simstruct,1);  //jzTc: genCtor thiz
    ObjectJc* othiz = (ObjectJc*)*addr_thiz;  //cast admissible because the instance have to be based on ObjectJc
    Output_Test_OrthOsc2* thiz = *addr_thiz;              //checkStrict_ObjectJc is invoked.
      //jzTc: genCtor, parameter identObj 
      //jzTc: get Parameter value
      //ssParamRec * identObj_paramInfo = ssGetRunTimeParamInfo(simstruct, 0); 
      //int32 * identObj_addr = (int32 *)identObj_paramInfo->data;  //gets the address of the input data in Simulink data area.
      //int32 identObj = *identObj_addr;  //for single elements.
      const mxArray* identObj_addr = ssGetSFcnParam(simstruct, 0);  //Tstep
      //int32 identObj = (int32) *mxGetPr(identObj_addr);  //assume Parameter is double, get the double (real_T)
      double* identObj_v = (double*) mxGetData(identObj_addr);  //assume Parameter is double, get the double (real_T)
      int32 identObj = 0;
      if(identObj_v !=null) { //check, mxGetData returns null if there are no data. Usual it should be correct.
        identObj = (int32) *identObj_v;  //assume Parameter is double, get the double (real_T)
      }

    { if( -1 == checkStrict_ObjectJc(othiz, (int32)sizeof(Output_Test_OrthOsc2), ident_newAllocated_ObjectJc, null, null)) {
        ssSetErrorStatus(simstruct,"malloc faulty for ctor_Output_Test_OrthOsc2");
      }
      //jzTc: Call of the constructor:
      ctor_Output_Test_OrthOsc2( thiz, identObj);
    }

  }
}

#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)) {
    
    //Object-FB:  
    //params: ix-init = 1, ix-step = 1, nrof = 1  
    //input ports: ix-init = X, ix-step = 0, nrof = 6  
    //output ports: thizInit = 0, thizStep = 1, ix-init = X, ix-step = 2, nrof = 2  

    char const* error = null;

    //Object-FB, thiz from DWork[1], handle from DWork[0]:    
    Output_Test_OrthOsc2* thiz = *(Output_Test_OrthOsc2 **)ssGetDWork(simstruct, 1 );
    uint32 hthiz = *(uint32*)ssGetDWork(simstruct, 0 );  //get handle stored in DWork in mdlStart(...)

    uint32* addr_thizInit = (uint32*)ssGetOutputPortSignal(simstruct, 0);  //address of thiz output for init time
    *addr_thizInit = hthiz;        //output the handle always, for Tinit time. Note: init().routines are exexuted at beginn of step time. 

    uint32* addr_thiz = (uint32*)ssGetOutputPortSignal(simstruct, 1);  //address of thiz output for step time
    *addr_thiz = hthiz;            //output the handle always, for Tstep time.

    //Sampletimes used: Tinit = true  Tstep = true

    //Port based sample time nrofInputs = 6, ixInputStep = 0, ixOutputStep = 2  
    int sti;
    time_T time_SmlkStep_ = ssGetT(simstruct);

    sti = ssGetInputPortSampleTimeIndex(simstruct,0);  //check the first input of the step method (zbnfop)
    //sti = ssGetOutputPortSampleTimeIndex(simstruct,1);  //The 2. Output is always in Tstep on an Object-FB
    if (ssIsSampleHit(simstruct, sti, tid)) {
      time_T time_SmlkStep_ = ssGetT(simstruct);

      if( isInitialized_ObjectJc((ObjectJc*)thiz) ) {

          //JZtc: The input port supplies the address of the array:      
          float_complex const* pq1 = (float_complex const*)ssGetInputPortSignal(simstruct, 0);

          //JZtc: The input port supplies the address of the array:      
          float const* m0 = (float const*)ssGetInputPortSignal(simstruct, 1);

          //JZtc: The input port supplies the address of the array:      
          float const* m1 = (float const*)ssGetInputPortSignal(simstruct, 2);

          //JZtc: The input port supplies the address of the array:      
          float const* m2 = (float const*)ssGetInputPortSignal(simstruct, 3);

          //JZtc: The input port supplies the address of the array:      
          float const* m3 = (float const*)ssGetInputPortSignal(simstruct, 4);

          //JZtc: The input port supplies the address of the array:      
          float const* e = (float const*)ssGetInputPortSignal(simstruct, 5);
    
        //invoke the step-routine: jzTc: genStepMethod()-E
        set_Output_Test_OrthOsc2(thiz, pq1, m0, m1, m2, m3, e);

   } } //

  }
}










    
/* 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)) {
    
  //Free the memory for the Output_Test_OrthOsc2 data //jzcmd: freeMem_mdlTerminate()-A
  Output_Test_OrthOsc2** addr_thiz = (Output_Test_OrthOsc2**)ssGetDWork(simstruct, 1); 
  Output_Test_OrthOsc2* thiz = *addr_thiz;
  if(thiz != NULL) {
    free(thiz);
  }
  //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)
{ 
  char buffer[1000] = {0}; //enough space for all String parameter.
  char* pBuffer = buffer; 
  //checked: int32 identObj

  //register all non tunable parameters. They are gotten in tlc via access to 'SFcnParamSettings.NAME'
  if (!ssWriteRTWParamSettings(simstruct, 1 
    , SSWRITE_VALUE_NUM, "identObj", mxGetPr(ssGetSFcnParam(simstruct, 0))[0]  
  ) ) { return;  } //an error occured

}

#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

