unsigned int sf_mex_unlock_call( int nlhs, mxArray * plhs[], int nrhs, const
  mxArray * prhs[] )
{
  char commandName[20];
  if (nrhs<1 || !mxIsChar(prhs[0]) )
    return 0;

  /* Possible call to get the checksum */
  mxGetString(prhs[0], commandName,sizeof(commandName)/sizeof(char));
  commandName[(sizeof(commandName)/sizeof(char)-1)] = '\0';
  if (strcmp(commandName,"sf_mex_unlock"))
    return 0;
  while (mexIsLocked()) {
    mexUnlock();
  }

  return(1);
}
Пример #2
0
/* ----
 */
void mexFunction(int nlhs, mxArray* plhs[],
                 int nrhs, const mxArray* prhs[])
{
    char id[512];
    if (nrhs == 0) {
        mexPrintf("Mex function installed\n");
        return;
    }

    if (mxGetString(prhs[0], id, sizeof(id)) != 0)
        mexErrMsgTxt("Identifier should be a string");
    else if (strcmp(id, stubids1_) == 0)
        mexStub1(nlhs,plhs, nrhs-1,prhs+1);
    else if (strcmp(id, "*profile on*") == 0) {
        if (!mexprofrecord_) {
            mexprofrecord_ = (int*) malloc(2 * sizeof(int));
            mexLock();
        }
        memset(mexprofrecord_, 0, 2 * sizeof(int));
    } else if (strcmp(id, "*profile off*") == 0) {
        if (mexprofrecord_) {
            free(mexprofrecord_);
            mexUnlock();
        }
        mexprofrecord_ = NULL;
    } else if (strcmp(id, "*profile report*") == 0) {
        if (!mexprofrecord_)
            mexPrintf("Profiler inactive\n");
        mexPrintf("%d calls to test_fortran2.mw:11\n", mexprofrecord_[1]);
    } else if (strcmp(id, "*profile log*") == 0) {
        FILE* logfp;
        if (nrhs != 2 || mxGetString(prhs[1], id, sizeof(id)) != 0)
            mexErrMsgTxt("Must have two string arguments");
        logfp = fopen(id, "w+");
        if (!logfp)
            mexErrMsgTxt("Cannot open log for output");
        if (!mexprofrecord_)
            fprintf(logfp, "Profiler inactive\n");
        fprintf(logfp, "%d calls to test_fortran2.mw:11\n", mexprofrecord_[1]);
        fclose(logfp);
    } else
        mexErrMsgTxt("Unknown identifier");
}
Пример #3
0
template<class base> inline void destroyObject(const mxArray *in)
{
    delete convertMat2HandlePtr<base>(in);
    mexUnlock();
}
Пример #4
0
template<typename T> inline void destroyObject(const mxArray *in)
{
    delete mat2HandlePtr<T>(in);
    mexUnlock();
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    char cmd[64];
    metricTreeCPP *theTree;
    
    if(nrhs>4) {
        mexErrMsgTxt("Too many inputs.");   
    }
    
    //Get the command string that is passed.
    mxGetString(prhs[0], cmd, sizeof(cmd));
    
    //prhs[0] is assumed to be the string telling
    if(!strcmp("metricTreeCPP", cmd)){
        size_t k, N;
        mxArray *retPtr;
        
        k=getSizeTFromMatlab(prhs[1]);
        N=getSizeTFromMatlab(prhs[2]);
        
        theTree =  new metricTreeCPP(k,N);
        
        //Convert the pointer to a Matlab matrix to return.
        retPtr=ptr2Matlab<metricTreeCPP*>(theTree);
        
        //Lock this mex file so that it can not be cleared until the object
        //has been deleted (This avoids a memory leak).
        mexLock();
        //Return the pointer to the tree
        plhs[0]=retPtr;
    } else if(!strcmp("buildTreeFromBatch",cmd)) {
        double *dataBatch;
        
        //Get the pointer back from Matlab.
        theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]);   
        
        checkRealDoubleArray(prhs[2]);
        dataBatch=reinterpret_cast<double*>(mxGetData(prhs[2]));
        
        theTree->buildTreeFromBatch(dataBatch);
    } else if(!strcmp("searchRadius",cmd)) {
        size_t numPoints;
        ClusterSetCPP<size_t> pointClust;
        ClusterSetCPP<double> distClust;
        double *point;
        double *radius;
        mxArray *clustParams[3];
        
        //Get the inputs
        theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]);
        checkRealDoubleArray(prhs[2]);
        checkRealDoubleArray(prhs[3]);
        point=reinterpret_cast<double*>(mxGetData(prhs[2]));
        radius=reinterpret_cast<double*>(mxGetData(prhs[3]));
        
        numPoints=mxGetN(prhs[2]);
        if(mxGetM(prhs[2])!=theTree->k){
            mexErrMsgTxt("Invalid point size passed.");
        }
        
        //Run the search; rangeCluster now contains the results.
        theTree->searchRadius(pointClust,distClust,point,radius, numPoints);
        
        //Put the results into an instance of the ClusterSet container 
        //class in Matlab.
        clustParams[0]=unsignedSizeMat2Matlab(pointClust.clusterEls,pointClust.totalNumEl,1);
        clustParams[1]=unsignedSizeMat2Matlab(pointClust.clusterSizes,pointClust.numClust,1);
        clustParams[2]=unsignedSizeMat2Matlab(pointClust.offsetArray,pointClust.numClust,1);
        
        //Return a ClusterSet containing the appropriate data.
        mexCallMATLAB(1, &(plhs[0]), 3,  clustParams, "ClusterSet");
        
        //If the distances should also be returned.
        if(nlhs>1) {
            clustParams[0]=doubleMat2Matlab(distClust.clusterEls,distClust.totalNumEl,1);
            clustParams[1]=unsignedSizeMat2Matlab(distClust.clusterSizes,distClust.numClust,1);
            clustParams[2]=unsignedSizeMat2Matlab(distClust.offsetArray,distClust.numClust,1);
        
            //Return a ClusterSet containing the appropriate data.
            mexCallMATLAB(1, &(plhs[1]), 3,  clustParams, "ClusterSet");
        }
    } else if(!strcmp("~metricTreeCPP", cmd)){
        theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]);

        delete theTree;
        //Unlock the mex file allowing it to be cleared.
        mexUnlock();
    } else if(!strcmp("getAllData", cmd)){
        size_t N;
        size_t k;
        
        theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]);
        N=theTree->N;
        k=theTree->k;
        
        plhs[0]=unsignedSizeMat2Matlab(theTree->DATAIDX,N, 1);
        if(nlhs>1) {
            plhs[1]=signedSizeMat2Matlab(theTree->innerChild,N, 1);
            if(nlhs>2) {
                plhs[2]=signedSizeMat2Matlab(theTree->outerChild,N, 1);
                if(nlhs>3) {
                    plhs[3]=doubleMat2Matlab(theTree->innerRadii,N, 1);
                    if(nlhs>4) {
                        plhs[4]=doubleMat2Matlab(theTree->outerRadii,N, 1);
                        if(nlhs>5) {
                            plhs[5]=doubleMat2Matlab(theTree->data,k, N);
                        }
                    }
                }
            }   
        }
    } else if(!strcmp("getN", cmd)) {
        theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]);
        plhs[0]=unsignedSizeMat2Matlab(&(theTree->N),1,1);
    } else if(!strcmp("getk", cmd)) {
        theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]);
        plhs[0]=unsignedSizeMat2Matlab(&(theTree->k),1,1);
    }else {
        mexErrMsgTxt("Invalid string passed to metricTreeCPPInt.");
    }
}
Пример #6
0
void mexFunction(	int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{   
    int i,j, k, status,buflen,Cnt, Hndl, L,M,N,  NumHandles, commandswitch;
    
    int *HndlArray;
    mxArray  *mymxArray;
    double *myDblPr;
    chtype RequestType;
    
    char PVName[PV_NAME_LENGTH_MAX+1];
    // char MCAMessageString[MCA_MESSAGE_STRING_LENGTH_MAX+1];
    
    
      

    dbr_string_t StrBuffer;
    
        
    
    const char *MCAInfoFields[]={"PVName","ElementCount","NativeType","State","MCAMessage","Host"};
    char *NativeTypeStrings[] = {"STRING","INT","FLOAT","ENUM","CHAR","LONG","DOUBLE"};
    


    
    if(!CA_INITIALIZED) // Initialize CA if not initialized (first call)
    {   mexPrintf("Initializing MATLAB Channel Access ... \n");
        status = ca_task_initialize();
        if(status!=ECA_NORMAL)
            mexErrMsgTxt("Unable to initialise Challel Access\n");
        CA_INITIALIZED = true;
        // Register a function to be called when a this mex-file is cleared from memory
        // with 'clear' or when exitting MATLAB
        mexAtExit(mca_cleanup);
        // Lock the mex-file so that it can not be cleared without explicitly
        // mexUnclock
        mexLock();
        
        //start periodic polling:
/*        PollTimerHandle = SetTimer(NULL,NULL,MCA_POLL_PERIOD,background_poll);
        if(PollTimerHandle)
            mexPrintf("Periodic CA polling started! System Timer ID: %u\n",PollTimerHandle);
        else
            mexWarnMsgTxt("Failed to start periodic CA polling\n");
 */       
        
    }

    commandswitch = (int)mxGetScalar(prhs[0]);
   
    switch(commandswitch)
    {  case 0: 
            mexUnlock();
            break;
    
        case 1: // MCAOPEN - add channel(s) by PV names, all arguments following prhs[0]
               // must be strings - names of PV's
            for(i=1;i<nrhs;i++)
            {   mxGetString(prhs[i],PVName,PV_NAME_LENGTH_MAX+1);
                status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID));
                if(status == ECA_NORMAL) // if not - go on to the next PV name
                {   status = ca_pend_io(MCA_SEARCH_TIMEOUT);
                    if (status == ECA_NORMAL)
                    {   // Allocate persistent memory for the DataBuffer on this channel
                        // to hold all elements of the DBR_XXX type
                        // nearest to the native type
                        // RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        // Cnt=ca_element_count(CHNLS[HandlesUsed].CHID);
                        
                        
                        CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID);
                        CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        CHNLS[HandlesUsed].MonitorEventCount = 0;
                        
                        switch(CHNLS[HandlesUsed].NativeType2DBR)
                        {   case DBR_STRING:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t));
                                
                            break;
                        
                            case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                        
                            case DBR_FLOAT:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); 
                            break;
                
                            case DBR_ENUM:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); 
                            break;
                
                            case DBR_CHAR:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); 
                            break;
                    
                            case DBR_LONG:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                    
                            case DBR_DOUBLE:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); 
                            break;
                        }   
                        mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer);
                        
                                 
                        if(CHNLS[HandlesUsed].NativeType2DBR==DBR_STRING) // CACHE
                        {   if(CHNLS[HandlesUsed].NumElements==1) // Create MATLAB string - originally empty
                                CHNLS[HandlesUsed].CACHE = mxCreateString("");
                            else // Create MATLAB cell array of strings
                            {   CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements);
                                for(k=0;k<CHNLS[HandlesUsed].NumElements;k++)
                                {   mymxArray = mxCreateString("");
                                    mexMakeArrayPersistent(mymxArray);
                                    mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray);
                                }
                            }
                        }
                        else // Make CACHE a numeric mxArray 
                        {    CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL);  
                        }
                        
                        mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE);
                        
                        plhs[i-1]=mxCreateScalarDouble(++HandlesUsed);                        
                    
                    }
                    else
                        plhs[i-1]=mxCreateScalarDouble(0);

                }
                else
                    plhs[i-1]=mxCreateScalarDouble(0);
            } break;
            
        
        case 2:// MCAOPEN - add channel(s) by PV names. The arguments following prhs[0]
               // argument must be a cell array of strings - PV names
            
            L = mxGetM(prhs[1])*mxGetN(prhs[1]);
            plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL);
            myDblPr = mxGetPr(plhs[0]);
            
            for(i=0;i<L;i++)
            {   mymxArray = mxGetCell(prhs[1],i);
                mxGetString(mymxArray,PVName,PV_NAME_LENGTH_MAX+1);
                status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID));
                if(status == ECA_NORMAL) // if not - go on to the next PV name
                {   status = ca_pend_io(MCA_IO_TIMEOUT);
                    if (status == ECA_NORMAL)
                    {   // Allcate persistent memory for the DataBuffer on this channel
                        //RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID);
                        CHNLS[HandlesUsed].MonitorEventCount = 0;
                        //Cnt=ca_element_count(CHNLS[HandlesUsed].CHID);
                        switch(CHNLS[HandlesUsed].NativeType2DBR)
                        {   case DBR_STRING:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t)); 
                            break;
                        
                            case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                        
                            case DBR_FLOAT:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); 
                            break;
                
                        
                            case DBR_ENUM:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); 
                            break;
                
                            case DBR_CHAR:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); 
                            break;
                    
                            case DBR_LONG:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                    
                            case DBR_DOUBLE:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); 
                            break;
                        }   
                        mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer);   
                        
                        if(CHNLS[HandlesUsed].NativeType2DBR == DBR_STRING) // CACHE
                        {   CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements);
                            for(k=0;k<CHNLS[HandlesUsed].NumElements;k++)
                            {   mymxArray = mxCreateString(StrBuffer);
                                mexMakeArrayPersistent(mymxArray);
                                mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray);
                            }
                        }
                        else
                        {    CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL);  
                        }
                        
                        mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE);
                        
                        
                        myDblPr[i] = ++HandlesUsed;
                    }
                    else
                        myDblPr[i] = 0;
                }
                else
                    myDblPr[i] = 0;
            } break;
            
       case 3: // MCAOPEN Return names of connected channels as cell array of strings
            plhs[0] = mxCreateCellArray(1, &HandlesUsed);
            for(i=0;i<HandlesUsed;i++)
            {   if(CHNLS[i].CHID!=NULL)
                    {   mymxArray = mxCreateString(ca_name(CHNLS[i].CHID));
                        mxSetCell(plhs[0], i, mymxArray);
                    }
                else
                    {   mymxArray = mxCreateString("");
                        //mexPrintf("Handle: %d PV: %s\n",i+1, "Cleared Channel");
                        mxSetCell(plhs[0], i, mymxArray);
                    }
              } break;
        
        
         
        case 5: // MCACLOSE permanently clear channel
            Hndl = (int)mxGetScalar(prhs[1]);
            if(Hndl<1 || Hndl>HandlesUsed)
                mexErrMsgTxt("Handle out of range");  

            // If a monitor is installed, set the EVID pointer to NULL 
            // ca_clear_event dos not do it by itself

            if(CHNLS[Hndl-1].EVID) 
                CHNLS[Hndl-1].EVID = NULL;
                
            // If there is Callback String - destroy it
            if(CHNLS[Hndl-1].MonitorCBString)
            {   mxFree(CHNLS[Hndl-1].MonitorCBString); 
                CHNLS[Hndl-1].MonitorCBString =NULL;
            }    
            
            if(ca_state(CHNLS[Hndl-1].CHID)==3)
                mexWarnMsgTxt("Channel previously cleared");
            else
                if(ca_clear_channel(CHNLS[Hndl-1].CHID)!=ECA_NORMAL)
                    mexErrMsgTxt("ca_clear_channel failed");

            break;
            
        case 10: // MCAINFO return channels info as MATLAB structure array
            if(HandlesUsed>0)
            {   plhs[0] = mxCreateStructMatrix(1,HandlesUsed,6,MCAInfoFields);
                
                for(i=0;i<HandlesUsed;i++)
                {   mxSetFieldByNumber(plhs[0],i,0,mxCreateString(ca_name(CHNLS[i].CHID)));
                    mxSetFieldByNumber(plhs[0],i,1,mxCreateScalarDouble(ca_element_count(CHNLS[i].CHID)));
                    mxSetFieldByNumber(plhs[0],i,5,mxCreateString(ca_host_name(CHNLS[i].CHID)));
                    
                    switch(ca_state(CHNLS[i].CHID))
                    {   case 1: // Disconnected due to Server or Network - may reconnect 
                            mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown"));
                            mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected"));
                            mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Disconnected due to server or network problem"));
                            break;
                        case 2: // Normal connection
                            mxSetFieldByNumber(plhs[0],i,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[i].CHID)]));
                            mxSetFieldByNumber(plhs[0],i,3,mxCreateString("connected"));
                            mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Normal connection"));
                            break;
                        case 3: // Disconnected by user
                            mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown"));
                            mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected"));
                            mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Permanently disconnected (cleared) by the user"));                    
                            break;
                    }    
                }
            }
            else
            {   mexWarnMsgTxt("No connected PV's found"); 
                plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
                
            }
            break;    
        
            
        case 11: // MCAINFO return info for 1 channel by handle number 
            Hndl = (int)mxGetScalar(prhs[1]);
            if(Hndl<1 || Hndl>HandlesUsed)
                mexErrMsgTxt("Handle out of range");  
                
            plhs[0] = mxCreateStructMatrix(1,1,6,MCAInfoFields);

            mxSetFieldByNumber(plhs[0],0,0,mxCreateString(ca_name(CHNLS[Hndl-1].CHID)));
            mxSetFieldByNumber(plhs[0],0,1,mxCreateScalarDouble(ca_element_count(CHNLS[Hndl-1].CHID)));
            mxSetFieldByNumber(plhs[0],0,5,mxCreateString(ca_host_name(CHNLS[Hndl-1].CHID)));
            
            switch(ca_state(CHNLS[Hndl-1].CHID))
            {  case 1: // Disconnected due to Server or Network - may reconnect 
                    mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown"));
                    mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected"));
                    mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Disconnected due to server or network problem"));
                    break;
                case 2: // Normal connection
                    mxSetFieldByNumber(plhs[0],0,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[Hndl-1].CHID)]));
                    mxSetFieldByNumber(plhs[0],0,3,mxCreateString("connected"));
                    mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Normal connection"));
                    break;
                case 3: // Disconnected by user
                    mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown"));
                    mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected"));
                    mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Permanently disconnected (cleared) by the user"));                    
                    break;
            };    
            
        break;    
        
        case 12: // MCASTATE return an array of status (1 - OK, 0 - disconnected or cleared) 
            if(HandlesUsed>0)
            {   plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL);
                myDblPr = mxGetPr(plhs[0]);
                for(i=0;i<HandlesUsed;i++)
                    myDblPr[i] = (double)(ca_state(CHNLS[i].CHID)==2);
            }
            else
            {   mexWarnMsgTxt("No connected PV's found"); 
                plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
                
            }
            break;    
        
        
        case 30: // poll
            ca_poll();
        break;
            

        case 50: // MCAGET Get PV values by their MCA handles
            
            for(i=0;i<nrhs-1;i++) // First loop: place all ca_get requests in the buffer
            {   Hndl = (int)mxGetScalar(prhs[1+i]); //start from[1]:  [0] argument is the commnads switch
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Invalid Handle");
                
                RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));
                Cnt = ca_element_count(CHNLS[Hndl-1].CHID);
                status = ca_array_get(RequestType,Cnt,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer);
                if(status!=ECA_NORMAL)
                    mexPrintf("Error in call to ca_array_get\n");
            }   
            
            status = ca_pend_io(MCA_GET_TIMEOUT);
            if(status!=ECA_NORMAL)
                mexErrMsgTxt("... ca_pend_io call timed out \n");
            
            
            for(i=0;i<nrhs-1;i++) // Another loop to copy data from temp structures to MATLAB
            
            {   Hndl = (int)mxGetScalar(prhs[1+i]);
                RequestType = RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));
                Cnt = ca_element_count(CHNLS[Hndl-1].CHID);
                
                if(RequestType==DBR_STRING)
                {   if(Cnt==1)
                        plhs[i] = mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer))));
                    else
                    {   plhs[i] = mxCreateCellMatrix(1,Cnt);
                        for(j=0;j<Cnt;j++)
                            mxSetCell(plhs[i], j, mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+j))));
                    }
                }
                
                else 
                {   plhs[i] = mxCreateDoubleMatrix(1,Cnt,mxREAL);
                    myDblPr = mxGetPr(plhs[i]);
                                        
                    switch(dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)))
                    
                    {   case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;    
                 
                        case DBR_FLOAT:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                
                        case DBR_ENUM:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                
                        case DBR_CHAR:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                    
                        case DBR_LONG:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                    
                        case DBR_DOUBLE:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                    } 

                }
                
            } break;            

            case 51: // MCAGET Get scalar PV of the same type 
                     // second argument is an array of handles
                     // returns an array of values
            
            myDblPr = mxGetPr(prhs[1]);
            M = mxGetM(prhs[1]);
            N = mxGetN(prhs[1]);
            
            NumHandles = M*N;
            plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL);
            
            for(i=0;i<NumHandles;i++) // First loop: place all ca_get requests in the buffer
            {   Hndl = (int)myDblPr[i];
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Invalid Handle");
                
                RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));
                status = ca_array_get(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(plhs[0])+i);
                if(status!=ECA_NORMAL)
                    mexPrintf("Error in call to ca_array_get\n");
            }   
            
            status = ca_pend_io(MCA_GET_TIMEOUT);
            if(status!=ECA_NORMAL)
                mexErrMsgTxt("... ca_pend_io call timed out \n");
            
            break;            

        
       
        case 70: // MCAPUT
            NumHandles = (nrhs-1)/2;
            for(i=0;i<NumHandles;i++)
            {   j = 2+i*2;
                Hndl = (int)mxGetScalar(prhs[1+i*2]); 
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Handle out of range - no values written");
                // Set the status to 0 - mcaput_callback will write 1, if successful
                CHNLS[Hndl-1].LastPutStatus = 0;    
                RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));            
                Cnt = ca_element_count(CHNLS[Hndl-1].CHID);
                
                
                // If a value to write is passed as a string - the number of elements to write 
                //   is 1 , NOT the length of the string returned by mxGetNumberOfElements
                if(mxIsChar(prhs[j])) 
                    L=1;
                else
                    L = min(mxGetNumberOfElements(prhs[j]),Cnt);
                

                // Copy double or string data from MATLAB prhs[] to DataBuffer
                // on each channel 
                
                if(RequestType==DBR_STRING)
                {   // STRING type is is passed as a cell array of strings
                    // A a 1-row MATLAB character array (1 string) may also be passed as a value
                    
                    if(mxIsChar(prhs[j]))
                    {   mxGetString(prhs[j], StrBuffer, sizeof(dbr_string_t));
                        strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer))),StrBuffer);
                        
                    }
                    else if(mxIsCell(prhs[j]))
                    {   for(k=0;k<L;k++)
                        {   mxGetString(mxGetCell(prhs[j],k), StrBuffer, sizeof(dbr_string_t));
                            strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+k)),StrBuffer);
                        }
                    }
                }
                else
                {   myDblPr = mxGetPr(prhs[j]); 
                    switch(RequestType)
                    {   
                        case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                        for(k=0;k<L;k++)
                            *((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_short_t)(myDblPr[k]);
                        break;    
                 
                        case DBR_FLOAT:
                        for(k=0;k<L;k++)
                            *((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_float_t)(myDblPr[k]);
                        break;
                
                        case DBR_ENUM:
                        for(k=0;k<L;k++)
                            *((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_enum_t)(myDblPr[k]);
                        break;
                
                        case DBR_CHAR:
                        for(k=0;k<L;k++)
                            *((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_char_t)(myDblPr[k]);
                        break;
                   
                        case DBR_LONG:
                        for(k=0;k<L;k++)
                            *((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_long_t)(myDblPr[k]);
                        break;
                    
                        case DBR_DOUBLE:
                        for(k=0;k<L;k++)
                            *((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_double_t)(myDblPr[k]);
                        break;
                    } 
                }            
 
                // place request in the que 
                status = ca_array_put_callback(RequestType,L,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer,
                                                   mcaput_callback,&(CHNLS[Hndl-1].LastPutStatus));

                 if(status!=ECA_NORMAL)
                    mexPrintf("ca_array_put_callback failed\n");
            }   
            
            status = ca_pend_event(MCA_PUT_TIMEOUT);
            
            plhs[0]=mxCreateDoubleMatrix(1,NumHandles,mxREAL);
            myDblPr = mxGetPr(plhs[0]);  
            
            for(i=0;i<NumHandles;i++)
            {   Hndl = (int)mxGetScalar(prhs[1+i*2]);
                myDblPr[i] = (double)CHNLS[Hndl-1].LastPutStatus;
                
            }
           
            break;
        
       case 80: // MCAPUT - fast unconfirmed put for scalar numeric PV's
        
            myDblPr = mxGetPr(prhs[1]);
            M = mxGetM(prhs[1]);
            N = mxGetN(prhs[1]);                
            NumHandles = M*N;
            
            plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL);
            myDblPr = mxGetPr(plhs[0]);  
            
            for(i=0;i<NumHandles;i++)
            {   myDblPr = mxGetPr(plhs[0]);
                Hndl = (int)(*(mxGetPr(prhs[1])+i)); 
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Handle out of range - no values written");

                status = ca_array_put(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(prhs[2])+i);

                if(status!=ECA_NORMAL)
                    {   myDblPr[i] = 0;
                        //mexPrintf("ca_array_put_callback failed\n");
                    }
                    else
                    {   myDblPr[i] = 1;
                    }
                    
            }   
            
            status = ca_pend_io(MCA_PUT_TIMEOUT);
            
            break;    
                 
            
        case 100: // MCAMON install Monitor or replace MonitorCBString
            
            Hndl = (int)mxGetScalar(prhs[1]); 
            
            // Check if the handle is within range 
            if(Hndl<1 || Hndl>HandlesUsed)
            {   plhs[0]=mxCreateScalarDouble(0);
                mexErrMsgTxt("Invalid Handle");
            }
            
            if(CHNLS[Hndl-1].EVID) // if VID is not NULL - another monitor is already installed - replace MonitorCBString
            {   if(CHNLS[Hndl-1].MonitorCBString) // Free memory for occupied by the old MonitorCBString
                {   mxFree(CHNLS[Hndl-1].MonitorCBString);
                    CHNLS[Hndl-1].MonitorCBString = NULL;
                }
                if(nrhs>2) // Check if the new string is specified
                {   if(mxIsChar(prhs[2]))
                    {   buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1;
                        CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen);
                        mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString);
                        mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); 
                    } 
                    else
                        mexErrMsgTxt("Third argument must be a string\n");
                }
                plhs[0]=mxCreateScalarDouble(1);
            }
            else // No monitor is presently installed;
            {   RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); // Closest to the native 
            
            
                if(nrhs>2)
                {   if(mxIsChar(prhs[2]))
                    {   buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1;
                        CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen);
                        mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString);
                        mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); 
                    } 
                    else
                        mexErrMsgTxt("Third argument must be a string\n");
                }
                else
                    CHNLS[Hndl-1].MonitorCBString = NULL;  // Set MonitorCBString to NULL so that mcaMonitorEventHandler only copies data to CACHE
            
                // Count argument set to 0 - native count
                status = ca_add_array_event(RequestType,0,CHNLS[Hndl-1].CHID, mcaMonitorEventHandler, &CHNLS[Hndl-1], 0.0, 0.0, 0.0, &(CHNLS[Hndl-1].EVID));
              
                if(status!=ECA_NORMAL)
                {   mexPrintf("ca_add_array_event failed\n");      
                    plhs[0]=mxCreateScalarDouble(0);
                }
                else
                {   ca_poll();
                    plhs[0]=mxCreateScalarDouble(1);
                }
            }   
            break;
            
        case 200: // Clear Monitor MCACLEARMON
            
            Hndl = (int)mxGetScalar(prhs[1]); 
            if(Hndl<1 || Hndl>HandlesUsed)
                mexErrMsgTxt("Invalid Handle");
            if(!CHNLS[Hndl-1].EVID) 
                mexErrMsgTxt("No monitor installed - can not clear");
                
            status = ca_clear_event(CHNLS[Hndl-1].EVID);
            if(status!=ECA_NORMAL)
                mexPrintf("ca_clear_event failed\n");
                
            // Set the EVID pointer to NULL (ca_clear_event dos not do it by itself)
            // to use as a FLAG that no monitors are installed 
            CHNLS[Hndl-1].EVID = NULL;
            // Reset
            CHNLS[Hndl-1].MonitorEventCount = 0;    
            // If there is Callback String - destroy it
            if(CHNLS[Hndl-1].MonitorCBString)
            {   mxFree(CHNLS[Hndl-1].MonitorCBString); 
                CHNLS[Hndl-1].MonitorCBString =NULL;
            }
                
          
        break;
          
        case 300: // MCACACHE Get Cached values of a monitored PV
            for(i=0;i<nrhs-1;i++)
            {   Hndl = (int)mxGetScalar(prhs[1+i]);
                // if(Hndl<1 || Hndl>HandlesUsed || !CHNLS[Hndl-1].CACHE)
                if(Hndl<1 || Hndl>HandlesUsed)
                    plhs[i] = mxCreateDoubleMatrix(0,0,mxREAL);
                else
                    {   plhs[i] = mxDuplicateArray(CHNLS[Hndl-1].CACHE);
                        CHNLS[Hndl-1].MonitorEventCount = 0;
                    }
            }       
          
        break;
        
        case 500: // MCAMON Info on installed monitors
            L = 0;
            HndlArray = (int*)mxCalloc(HandlesUsed,sizeof(int));
            
            for(i=0;i<HandlesUsed;i++) // Count installed monitors
            {   if(CHNLS[i].EVID)
                HndlArray[L++]=i+1;
            }       
            
            if(L>0)
            {   plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL);
                myDblPr = mxGetPr(plhs[0]);
                plhs[1] = mxCreateCellMatrix(1,L);
                for(i=0;i<L;i++)
                {   myDblPr[i] = (double)HndlArray[i];
                    mxSetCell(plhs[1],i,mxCreateString(CHNLS[HndlArray[i]-1].MonitorCBString));
                }
            }
            else
            {   plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
                plhs[1] = mxCreateCellMatrix(0,0);
            }
            
        break;
        
        case 510: // MCAMONEVENTS Event count fot monitors
                       
            plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL);
            myDblPr = mxGetPr(plhs[0]);
            for(i=0;i<HandlesUsed;i++)
                myDblPr[i]=(double)(CHNLS[i].MonitorEventCount);
            
        break;
        
        case 1000: // print timeout settings
            plhs[0] = mxCreateDoubleMatrix(3,1,mxREAL);
            mexPrintf("MCA timeout settings\n:");
            mexPrintf("mcaopen\t%f [s]\n",  MCA_SEARCH_TIMEOUT );
            mexPrintf("mcaget\t%f [s]\n",  MCA_GET_TIMEOUT ); 
            mexPrintf("mcaput\t%f [s]\n",  MCA_PUT_TIMEOUT );

            myDblPr = mxGetPr(plhs[0]);
            myDblPr[0] = MCA_SEARCH_TIMEOUT;
            myDblPr[1] = MCA_GET_TIMEOUT;
            myDblPr[2] = MCA_PUT_TIMEOUT;

            
        break;
        
        
        case 1001: // set MCA_SEARCH_TIMEOUT
            // return delay value
            MCA_SEARCH_TIMEOUT = mxGetScalar(prhs[1]);
            plhs[0] = mxCreateScalarDouble(MCA_SEARCH_TIMEOUT);
        break;
        
        case 1002: // set MCA_GET_TIMEOUT
            // return delay value
            MCA_GET_TIMEOUT = mxGetScalar(prhs[1]);
            plhs[0] = mxCreateScalarDouble(MCA_GET_TIMEOUT);
        break;
        
        case 1003: // set MCA_PUT_TIMEOUT
            // return delay value
            MCA_PUT_TIMEOUT = mxGetScalar(prhs[1]);
            plhs[0] = mxCreateScalarDouble(MCA_PUT_TIMEOUT);
        break;

    } 
}
Пример #7
0
void mexFunction (int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) {
		int rc, enabled;
		UINT32_T masterid = 0;
		time_t timallow = 0;
		UINT64_T memallow = 0;
		UINT64_T rss, vs;

		/* this function will be called upon unloading of the mex file */
		mexAtExit(exitFun);

		if (nrhs<3)
				mexErrMsgTxt ("invalid number of input arguments");

		if (mxIsScalar(prhs[0]))
				masterid = mxGetScalar(prhs[0]);
		else if (mxIsEmpty(prhs[0]))
				masterid = 0;
		else
				mexErrMsgTxt ("invalid input argument #1");

		if (mxIsScalar(prhs[1]))
				timallow = mxGetScalar(prhs[1]);
		else if (mxIsEmpty(prhs[1]))
				timallow = 0;
		else
				mexErrMsgTxt ("invalid input argument #2");

		if (mxIsScalar(prhs[2]))
				memallow = mxGetScalar(prhs[2]);
		else if (mxIsEmpty(prhs[2]))
				memallow = 0;
		else
				mexErrMsgTxt ("invalid input argument #3");

		if (masterid!=0 || timallow!=0 || memallow!=0) {
				enabled = 1;
				/* in this case the mex file is not allowed to be cleared from memory */
				if (!mexIsLocked())
						mexLock(); 
		}

		if (masterid==0 && timallow==0 && memallow==0) {
				enabled = 0;
				/* in this case the mex file is allowed to be cleared from memory */
#ifdef SOLUTION_FOR_UNEXPLAINED_CRASH
				if (mexIsLocked())
						mexUnlock(); 
#endif
		}

		if (!peerInitialized) {
				mexPrintf("watchdog: init\n");
				peerinit(NULL);
				peerInitialized = 1;
		}

		/* start the discover thread */
		pthread_mutex_lock(&mutexstatus);
		if (!discoverStatus) {
				pthread_mutex_unlock(&mutexstatus);
				mexPrintf("watchdog: spawning discover thread\n");
				rc = pthread_create(&discoverThread, NULL, discover, (void *)NULL);
				if (rc)
						mexErrMsgTxt("problem with return code from pthread_create()");
				else {
						/* wait until the thread has properly started */
						pthread_mutex_lock(&mutexstatus);
						if (!discoverStatus)
								pthread_cond_wait(&condstatus, &mutexstatus);
						pthread_mutex_unlock(&mutexstatus);
				}
		}
		else {
				pthread_mutex_unlock(&mutexstatus);
		}

		/* start the expire thread */
		pthread_mutex_lock(&mutexstatus);
		if (!expireStatus) {
				pthread_mutex_unlock(&mutexstatus);
				mexPrintf("watchdog: spawning expire thread\n");
				rc = pthread_create(&expireThread, NULL, expire, (void *)NULL);
				if (rc)
						mexErrMsgTxt("problem with return code from pthread_create()");
				else {
						/* wait until the thread has properly started */
						pthread_mutex_lock(&mutexstatus);
						if (!expireStatus)
								pthread_cond_wait(&condstatus, &mutexstatus);
						pthread_mutex_unlock(&mutexstatus);
				}
		}
		else {
				pthread_mutex_unlock(&mutexstatus);
		}

		if (timallow>0) {
				/* timallow should be relative to now */
				timallow += time(NULL);
		}

		if (memallow>0) {
				/* memallow should be in absolute numbers, add the current memory footprint */
				getmem(&rss, &vs);
				memallow += rss;
		}

		/* enable the watchdog: the expire thread will exit if the master is not seen any more */
		pthread_mutex_lock(&mutexwatchdog);
		watchdog.enabled  = enabled;
		watchdog.evidence = 0;
		watchdog.masterid = masterid;
		watchdog.memory   = memallow;
		watchdog.time     = timallow;
		pthread_mutex_unlock(&mutexwatchdog);

		if (enabled)
				mexPrintf("watchdog: enabled for masterid = %lu, time = %d, memory = %lu\n", masterid, timallow, memallow);
		else
				mexPrintf("watchdog: disabled for masterid = %lu, time = %d, memory = %lu\n", masterid, timallow, memallow);

		return;
} /* main */
//=========================================================================
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    //Documentation of the calling forms is given within each if clause

    if (!locked)
    {
        

        
        //NOTE: If we run clear all this will clear the definition of
        //this file and depending on whether or not we had open references
        //could cause Matlab to crash. By locking this file we prevent
        //clearing the file (which means we can't recompile it unless we
        //close Matlab) but we also prevent Matlab from crashing.
        //
        //TODO: Implement allowing unlock by reference counting
        //TODO: Alternatively we could pass in a command to unlock
        mexLock();
        locked = 1;
    }
    
    
    ADI_FileHandle fileH(0);
    
    
    //Setup output result code
    //-----------------------------------------------
    //Each function returns a result code, indicating if the function call
    //worked or not.
    ADIResultCode result;
    int *out_result; //Each function will return a result code as well as
    //possibly other values ..
    plhs[0]    = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL);
    out_result = (int *) mxGetData(plhs[0]);
    
    
    //Which function to call
    double function_option = mxGetScalar(prhs[0]);
    
    //Function list
    //--------------------------------------
    // 0  ADI_OpenFile
    // 1  ADI_GetNumberOfRecords
    // 2  ADI_GetNumberOfChannels
    // 3  ADI_GetNumTicksInRecord
    // 4  ADI_GetRecordTickPeriod
    // 5  ADI_GetNumSamplesInRecord
    // 6  ADI_CreateCommentsAccessor
    // 7  ADI_CloseCommentsAccessor
    // 8  ADI_GetCommentInfo
    // 9  ADI_NextComment
    // 10 ADI_GetSamples
    // 11 ADI_GetUnitsName
    // 12 ADI_GetChannelName
    // 13 ADI_CloseFile
    // 14 ADI_GetErrorMessage
    // 15 ADI_GetRecordSamplePeriod
    // 16 ADI_GetRecordTime
    // 17 ADI_CreateFile
    
    
    if (function_option == 0)
    {
        //  ADI_OpenFile   <>   openFile
        //  ===================================================
        //  [result_code,file_h] = sdk_mex(0,file_path)
        
        wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]);

        //long openMode  = getLongInput(prhs,2);
        
        result        = ADI_OpenFile(w_file_path, &fileH, kOpenFileForReadOnly);
        out_result[0] = result;

        setFileHandle(plhs,result,fileH);
    }
    else if (function_option == 0.5)
    {
		//This is a call to open the file for reading and writing
		//
        //TODO: Replace this with an input to function 0
        
        wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]);

        result        = ADI_OpenFile(w_file_path, &fileH, kOpenFileForReadAndWrite);
        out_result[0] = result;

        setFileHandle(plhs,result,fileH);
    }
    else if (function_option == 1)
    {
        //  ADI_GetNumberOfRecords   <>   getNumberOfRecords
        //  ======================================================
        //  [result_code,n_records] = sdk_mex(1,file_handle)
        
        long nRecords = 0;
        fileH         = getFileHandle(prhs);
        
        //ADIResultCode ADI_GetNumberOfRecords(ADI_FileHandle fileH, long* nRecords);
        result        = ADI_GetNumberOfRecords(fileH,&nRecords);
        out_result[0] = result;
        setLongOutput(plhs,1,nRecords);
        
    }
    else if (function_option == 2)
    {
        //  ADI_GetNumberOfChannels   <>   getNumberOfChannels
        //  ========================================================
        //  [result_code,n_channels] = sdk_mex(2,file_handle)
        
        long nChannels = 0;
        fileH = getFileHandle(prhs);
        
        //ADIResultCode ADI_GetNumberOfChannels(ADI_FileHandle fileH, long* nChannels);
        result         = ADI_GetNumberOfChannels(fileH,&nChannels);
        out_result[0]  = result;
        setLongOutput(plhs,1,nChannels);
    }
    else if (function_option == 3)
    {
        //  ADI_GetNumTicksInRecord   <>   getNTicksInRecord
        //  ======================================================
        //  [result,n_ticks] = sdk_mex(3,file_handle,record_idx_0b)
        
        fileH = getFileHandle(prhs);
        
        //0 or 1 based ...
        long record = getLongInput(prhs,2);
        long nTicks = 0;
        
        //ADIResultCode ADI_GetNumTicksInRecord(ADI_FileHandle fileH, long record, long* nTicks);
        result         = ADI_GetNumTicksInRecord(fileH,record,&nTicks);
        out_result[0]  = result;
        setLongOutput(plhs,1,nTicks);
    }
    else if (function_option == 4)
    {
        //  ADI_GetRecordTickPeriod  <>  getTickPeriod
        //  =========================================================
        //  [result,s_per_tick] = sdk_mex(4,file_handle,record_idx_0b,channel_idx_0b)
        
        fileH          = getFileHandle(prhs);
        
        long record  = getLongInput(prhs,2);
        long channel = getLongInput(prhs,3);
        double secsPerTick = 0;
        
        //ADIResultCode ADI_GetRecordTickPeriod(ADI_FileHandle fileH, long channel, long record, double* secsPerTick);
        out_result[0] = ADI_GetRecordTickPeriod(fileH,channel,record,&secsPerTick);
        setDoubleOutput(plhs,1,secsPerTick);
        
    }
    else if (function_option == 5)
    {
        //  ADI_GetNumSamplesInRecord  <>  getNSamplesInRecord
        //  ========================================================
        //  [result_code,n_samples] = sdk_mex(5,file_handle,record_idx_0b,channel_idx_0b);
        
        fileH          = getFileHandle(prhs);
        
        long record   = getLongInput(prhs,2);
        long channel  = getLongInput(prhs,3);
        long nSamples = 0;
        
        //ADIResultCode ADI_GetNumSamplesInRecord(ADI_FileHandle fileH, long channel, long record, long* nSamples);
        out_result[0] = ADI_GetNumSamplesInRecord(fileH,channel,record,&nSamples);
        setLongOutput(plhs,1,nSamples);
    }
    else if (function_option == 6)
    {
        //  ADI_CreateCommentsAccessor  <>  getCommentAccessor
        //  ========================================================
        //  [result_code,comments_h] = sdk_mex(6,file_handle,record_idx_0b);
        
        ADI_CommentsHandle commentsH(0);
        fileH         = getFileHandle(prhs);
        long record   = getLongInput(prhs,2);
        
        //ADIResultCode ADI_CreateCommentsAccessor(ADI_FileHandle fileH, long record, ADI_CommentsHandle* commentsH);
        result = ADI_CreateCommentsAccessor(fileH,record,&commentsH);
        out_result[0] = result;
        
        int64_t *p_c;
        plhs[1]    = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL);
        p_c = (int64_t *) mxGetData(plhs[1]);
        if (result == 0)
            p_c[0] = (int64_t)commentsH;
        else
            p_c[0] = 0;
    }
    else if (function_option == 7)
    {
        //  ADI_CloseCommentsAccessor   <>   closeCommentAccessor
        //  ========================================================
        //  result_code = sdk_mex(7,comments_h);
        
        ADI_CommentsHandle commentsH = getCommentsHandle(prhs);
        
        //ADIResultCode ADI_CloseCommentsAccessor(ADI_CommentsHandle *commentsH);
        out_result[0] = ADI_CloseCommentsAccessor(&commentsH);
    }
    else if (function_option == 8)
    {
        //  ADI_GetCommentInfo   <>   getCommentInfo
        //  ====================================================
        //  [result_code,comment_string,comment_length,tick_pos,channel,comment_num] = sdk_mex(8,comment_h)
        //
        //  Status: Done
        
        ADI_CommentsHandle commentsH = getCommentsHandle(prhs);
        
        wchar_t *messageOut = getStringOutputPointer(plhs,1);
        long tickPos    = 0;
        long channel    = 0;
        long commentNum = 0;
        long textLen    = 0;
        
        
        //ADIResultCode ADI_GetCommentInfo(ADI_CommentsHandle commentsH, long *tickPos, long *channel, long *commentNum, wchar_t* text,long maxChars, long *textLen);
        //          tickPos                 - receives the tick position of the comment in the record [outparam]
        //          commentNum              - receives the number of the comment [outparam]
        //          channel                 - receives the channel of the comment (-1 for all channel comments) [outparam]
        //          text                    - buffer to receive null terminated text for the comment (optional, may be NULL) [outparam]
        //          maxChars                - the size of the text buffer in wchar_t s. The text will be truncated to fit in this size
        //          textLen                 - receives the number of characters needed to hold the full comment text,
        //                                    even if parameter text is NULL (optional, may be NULL) [outparam]
        
        out_result[0] = ADI_GetCommentInfo(commentsH,&tickPos,&channel,&commentNum,messageOut,MAX_STRING_LENGTH,&textLen);
        
        setLongOutput(plhs,2,textLen);
        setLongOutput(plhs,3,tickPos);
        setLongOutput(plhs,4,channel);
        setLongOutput(plhs,5,commentNum);
        
    }
    else if (function_option == 9)
    {
        
        //  ADI_NextComment  <>  advanceComments
        //  ==================================================
        //  result_code = adi.sdk_mex(9,comments_h);
        //
        //  Returns kResultNoData if there are no more comments ...
        //
        //  Status: Done
        
        ADI_CommentsHandle commentsH = getCommentsHandle(prhs);
        
        //ADIResultCode ADI_NextComment(ADI_CommentsHandle commentsH);
        out_result[0] = ADI_NextComment(commentsH);
    }
    else if (function_option == 10)
    {
        //  ADI_GetSamples   <>   getChannelData
        //  ===========================================================
        //  [result,data,n_returned] = sdk_mex(10,file_h,channel_0b,record_0b,startPos,nLength,dataType)
        
        fileH = getFileHandle(prhs);
        
        long channel  = getLongInput(prhs,2);
        long record   = getLongInput(prhs,3);
        long startPos = getLongInput(prhs,4);
        long nLength  = getLongInput(prhs,5);
        
        ADICDataFlags dataType = static_cast<ADICDataFlags>(getLongInput(prhs,6));

        plhs[1]     = mxCreateNumericMatrix(1,(mwSize)nLength,mxSINGLE_CLASS,mxREAL);
        float *data = (float *)mxGetData(plhs[1]);
        
        long returned = 0;
        // Retrieves a block of sample data from the file into a buffer. Samples are in physical
        // prefixed units.
        //DLLEXPORT ADIResultCode ADI_GetSamples(ADI_FileHandle fileH, long channel, long record, long startPos,
        //  ADICDataFlags dataType, long nLength, float* data, long* returned);
        out_result[0] = ADI_GetSamples(fileH,channel,record,startPos,dataType,nLength,data,&returned);
        //out_result[0] = ADI_GetSamples(fileH,channel,record,startPos,kADICDataAtSampleRate,nLength,data,&returned);
        
        setLongOutput(plhs,2,returned);
        
        //out_result[0] = 4;
    }
    else if (function_option == 11)
    {
        //  ADI_GetUnitsName   <>  getUnits
        //  =======================================
        //  [result_code,str_data,str_length] = sdk_mex(11,file_h,record,channel);
        
        //Inputs
        fileH        = getFileHandle(prhs);
        long record  = getLongInput(prhs,2);
        long channel = getLongInput(prhs,3);
        
        //Outputs
        long textLen      = 0;
        wchar_t *unitsOut = getStringOutputPointer(plhs,1);
        
        
        // Retrieves the prefixed units of a channel, as a string.
        //
        //ADIResultCode ADI_GetUnitsName(ADI_FileHandle fileH, long channel, long record, wchar_t* units, long maxChars, long *textLen);
        out_result[0] = ADI_GetUnitsName(fileH, channel, record, unitsOut, MAX_STRING_LENGTH, &textLen);
        setLongOutput(plhs,2,textLen);
    }
    else if (function_option == 12)
    {
        //  ADI_GetChannelName   <>   getChannelName
        //  =============================================
        //  [result_code,str_data,str_length] = sdk_mex(12,file_h,channel);
        
        
        //Inputs
        fileH        = getFileHandle(prhs);
        long channel = getLongInput(prhs,2);
        
        //Outputs
        long textLen        = 0;
        wchar_t *nameOut    = getStringOutputPointer(plhs,1);
        
        // Retrieves the name of a channel, as a string.
        
        //ADIResultCode ADI_GetChannelName(ADI_FileHandle fileH, long channel, wchar_t* name, long maxChars, long *textLen);
        out_result[0] = ADI_GetChannelName(fileH, channel, nameOut, MAX_STRING_LENGTH, &textLen);
        setLongOutput(plhs,2,textLen);
    }
    else if (function_option == 13)
    {
        //  ADI_CloseFile   <>   closeFile
        //  ==============================================================
        //
        
        fileH          = getFileHandle(prhs);
        result         = ADI_CloseFile(&fileH);
        out_result[0]  = result;
    }
    else if (function_option == 14)
    {
        //  ADI_GetErrorMessage   <>   getErrorMessage
        //  ==============================================================
        //  err_msg = sdk_mex(14,error_code)
        
        long textLen        = 0;
        
        wchar_t *messageOut = getStringOutputPointer(plhs,1);
        
        ADIResultCode code  = (ADIResultCode)getLongInput(prhs,1);
        
        //ADIResultCode ADI_GetErrorMessage(ADIResultCode code, wchar_t* messageOut, long maxChars, long *textLen);
        out_result[0] = ADI_GetErrorMessage(code, messageOut, MAX_STRING_LENGTH, &textLen);
        setLongOutput(plhs,2,textLen);
        
    }
    else if (function_option == 15)
    {
        //   ADI_GetRecordSamplePeriod   <>   getSamplePeriod
        //   ==============================================================
        //   [result_code,dt_channel] = sdk_mex(15,file_h,record,channel)
        
        fileH        = getFileHandle(prhs);
        long record  = getLongInput(prhs,2);
        long channel = getLongInput(prhs,3);
        double secsPerSample = 0;
        
        out_result[0] = ADI_GetRecordSamplePeriod(fileH, channel, record, &secsPerSample);
        setDoubleOutput(plhs,1,secsPerSample);
    }
    else if (function_option == 16)
    {
        //   ADI_GetRecordTime   <>   getRecordStartTime
        //   ==============================================================
        //   [result_code,trigger_time,frac_secs,trigger_minus_rec_start] = sdk_mex(16,file_h,record)
        
        fileH        = getFileHandle(prhs);
        long record  = getLongInput(prhs,2);
        
        time_t triggerTime = 0;
        double fracSecs    = 0;
        long   triggerMinusStartTicks = 0;
        
        //Retrieves time information about the specified record.
        //The trigger time is the time origin of the record and may differ from the start time if
        //there is a pre or post trigger delay, as specified by the trigMinusRecStart parameter.
        // Params: fileH             - ADI_FileHandle for the open file
        //         record            - the record index (starting from 0)
        //         triggerTime       - time_t receives the date and time of the trigger
        //                             position for the new record. Measured as number of
        //                             seconds from 1 Jan 1970
        //         fracSecs          - receives the fractional seconds part of
        //                             the record trigger time ('triggerTime' parameter)
        //         trigMinusRecStart - trigger-time-minus-record-start-ticks. Receives the
        //                             difference between the time of trigger tick and the first
        //                             tick in the record. This +ve for pre-trigger delay and
        //                             -ve for post-trigger delay.
        // Return: a ADIResultCode for result of the operation
        
        //DLLEXPORT ADIResultCode ADI_GetRecordTime(ADI_FileHandle fileH, long record, time_t *triggerTime,
        //double *fracSecs, long *triggerMinusStartTicks);
        
        out_result[0] = ADI_GetRecordTime(fileH, record, &triggerTime, &fracSecs, &triggerMinusStartTicks);
        
        setDoubleOutput(plhs,1,(double)triggerTime);
        setDoubleOutput(plhs,2,fracSecs);
        setLongOutput(plhs,3,triggerMinusStartTicks);
        
    }
    else if (function_option == 17){
        //
        //   ADI_CreateFile   <>   createFile
        //   ==============================================================
        //   [result_code,file_h] = sdk_mex(17,file_path)
        //    
        //   Implemented via sdk.createFile
        
        wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]);
        
        result        = ADI_CreateFile(w_file_path, &fileH);
        out_result[0] = result;
        
        setFileHandle(plhs,result,fileH);
    }
    else if (function_option == 18){
        //
        //   ADI_SetChannelName  <>  setChannelName
        //   ==============================================================
        //   [result_code,file_h] = sdk_mex(18,file_h,channel,name)
        //
        //   Implemented via sdk.setChannelName
        
        fileH = getFileHandle(prhs);
        long channel = getLongInput(prhs,2);
        wchar_t *channel_name = (wchar_t *)mxGetData(prhs[3]);
        
        out_result[0] = ADI_SetChannelName(fileH, channel, channel_name);
    }
    else if (function_option == 19){
        //
        //   ADI_CreateWriter  <>  createDataWriter
        //   ===========================================
        //   [result_code,writer_h] = sdk_mex(19,file_h)
        //
        //  Implemented via sdk.createDataWriter
        
        ADI_WriterHandle writerH(0);
        
        fileH = getFileHandle(prhs);
        
        result        = ADI_CreateWriter(fileH,&writerH);
        out_result[0] = result;
        
        setWriterHandle(plhs,result,writerH);
    }
    else if (function_option == 20){
        //
        //   ADI_SetChannelInfo  <>  setChannelInfo
        //   ===========================================
        //   [result_code] = sdk_mex(20,writer_h,channel,enabled,seconds_per_sample,units,limits)
        //
        //   implemented via adi.sdk.setChannelInfo
        
        ADI_WriterHandle writerH = getWriterHandle(prhs);
        
        long channel = getLongInput(prhs,2);
        int enabled  = getIntInput(prhs,3);
        double seconds_per_sample = getDoubleInput(prhs,4);
        wchar_t *units = (wchar_t *)mxGetData(prhs[5]);
        float *temp_limits = (float *)mxGetData(prhs[5]);
        ADIDataLimits limits;
        limits.mMaxLimit = temp_limits[1];
        limits.mMinLimit = temp_limits[0];
        
        out_result[0] = ADI_SetChannelInfo(writerH, channel, enabled, seconds_per_sample, units, &limits);
        
//       DLLEXPORT ADIResultCode ADI_SetChannelInfo(ADI_WriterHandle writerH, long channel, int enabled,
//       double secondsPerSample, const wchar_t* units, const ADIDataLimits *limits);
        
    }
    else if (function_option == 21){
        //
        //   ADI_StartRecord  <>  startRecord
        //   ===========================================
        //   result_code = sdk_mex(21, writerH, trigger_time, fractional_seconds, trigger_minus_rec_start)
        //
        //   implemented via adi.sdk.startRecord
        
        ADI_WriterHandle writerH = getWriterHandle(prhs);
        time_t trigger_time = (time_t)getDoubleInput(prhs,2);
        double fractional_seconds = getDoubleInput(prhs,3);
        long trigger_minus_rec_start = getLongInput(prhs,4);
        
        out_result[0] = ADI_StartRecord(writerH, trigger_time, fractional_seconds, trigger_minus_rec_start);
        
//            DLLEXPORT ADIResultCode ADI_StartRecord(ADI_WriterHandle writerH, time_t triggerTime,
//       double fracSecs, long triggerMinusStartTicks);
    }
    else if (function_option == 22){
        //
        //   ADI_AddChannelSamples  <>  addChannelSamples
        //   ===========================================
        //   [result_code,new_ticks_added] = sdk_mex(22, writerH, channel, data, n_samples)
        //
        //  adi.sdk.addChannelSamples
        
        ADI_WriterHandle writerH = getWriterHandle(prhs);
        long channel = getLongInput(prhs,2);
        float *data  = (float *)mxGetData(prhs[3]);
        long n_samples = (long)mxGetNumberOfElements(prhs[3]);
        long new_ticks_added = 0;
        
        out_result[0] = ADI_AddChannelSamples(writerH, channel, data, n_samples, &new_ticks_added);
        
        setLongOutput(plhs,1,new_ticks_added);
        
//       DLLEXPORT ADIResultCode ADI_AddChannelSamples(ADI_WriterHandle writerH, long channel,
//       float* data, long nSamples, long *newTicksAdded);
    }
    else if (function_option == 23){
        //
        //   ADI_FinishRecord  <>  finishRecord
        //   ===========================================
        //   [result_code] = sdk_mex(23, writerH)
        //
        //  Implemented via adi.sdk.finishRecord
        
        ADI_WriterHandle writerH = getWriterHandle(prhs);
        
        out_result[0] = ADI_FinishRecord(writerH);
        
//        DLLEXPORT ADIResultCode ADI_FinishRecord(ADI_WriterHandle writerH);
    }
    else if (function_option == 24){
        //
        //   ADI_CommitFile  <>  commitFile
        //   ===========================================
        //   [result_code] = sdk_mex(24, writerH, flags)
        //
        //  Implemented via adi.sdk.commitFile
        
        ADI_WriterHandle writerH = getWriterHandle(prhs);
        
        //TODO: What are the flags??????
        
        out_result[0] = ADI_CommitFile(writerH, 0);
        
//         DLLEXPORT ADIResultCode ADI_CommitFile(ADI_WriterHandle writerH, long flags);
    }
    else if (function_option == 25){
        //
        //   ADI_CloseWriter  <>  closeWriter
        //   ===========================================
        //   [result_code] = sdk_mex(25, writerH)
        //
        //  Implemented via adi.sdk.closeWriter
        
        ADI_WriterHandle writerH = getWriterHandle(prhs);
        
        out_result[0] = ADI_CloseWriter(&writerH);
        
//      DLLEXPORT ADIResultCode ADI_CloseWriter(ADI_WriterHandle *writerH);
    }
    else if (function_option == 26){
        //
        //   ADI_AddComment  <>  addComment
        //   ===========================================
        //   [result_code, comment_number] =
        //      sdk_mex(26, file_h, channel, record, tick_position, text)
        //
        //  Implemented via adi.sdk.addComment
        
        fileH = getFileHandle(prhs);
        long channel = getLongInput(prhs,2);
        long record  = getLongInput(prhs,3);
        long tick_position = getLongInput(prhs,4);
        wchar_t *text = (wchar_t *)mxGetData(prhs[5]);
        long comment_number = 0;
        //long comment_number = getLongInput(prhs,6);
        
        out_result[0] = ADI_AddComment(fileH, channel, record, tick_position, text, &comment_number);
        
        setLongOutput(plhs,1,comment_number);
        
//        DLLEXPORT ADIResultCode ADI_AddComment(ADI_FileHandle fileH, long channel, long record, long tickPos,
//       const wchar_t* text, long* commentNum);
    }
    else if (function_option == 27){
        //
        //   ADI_DeleteComment  <>  deleteComment
        //   ===========================================
        //   result_code = sdk_mex(27,file_h,comment_number)
        //
        //  Implemented via adi.sdk.deleteComment
        
        fileH = getFileHandle(prhs);
        long comment_number = getLongInput(prhs,2);
        
        out_result[0] = ADI_DeleteComment(fileH,comment_number);
        
//         DLLEXPORT ADIResultCode ADI_DeleteComment(ADI_FileHandle fileH, long commentNum);
    }
    else if (function_option == 100){
        mexUnlock();
        locked = 0;
    }
    else
    {
        mexErrMsgIdAndTxt("adinstruments:sdk_mex",
                "Invalid function option");
    }

    //ADI_GetRecordSamplePeriod
    //ADI_GetRecordTime
}