void report(FILE* fp, const char* conn_type, void* handle, bool buffered) { int error, conn_error; CNVConnectionStatus status; fprintf(fp, " Connection type: %s", conn_type); if (handle == 0) { fprintf(fp, " Status: <not being used>\n"); return; } error = CNVGetConnectionAttribute(handle, CNVConnectionStatusAttribute, &status); ERROR_CHECK("CNVGetConnectionAttribute", error); fprintf(fp, " status: %s", connectionStatus(status)); error = CNVGetConnectionAttribute(handle, CNVConnectionErrorAttribute, &conn_error); ERROR_CHECK("CNVGetConnectionAttribute", error); if (conn_error < 0) { fprintf(fp, " error present: %s", CNVGetErrorDescription(conn_error)); } if (buffered) { int nitems, maxitems; error = CNVGetConnectionAttribute(handle, CNVClientBufferNumberOfItemsAttribute, &nitems); ERROR_CHECK("CNVGetConnectionAttribute", error); error = CNVGetConnectionAttribute(handle, CNVClientBufferMaximumItemsAttribute, &maxitems); ERROR_CHECK("CNVGetConnectionAttribute", error); fprintf(fp, " Client buffer: %d items (buffer size = %d)", nitems, maxitems); } fprintf(fp, "\n"); }
/// called by StatusCallback() when status of a network shared variable changes void NetShrVarInterface::statusCallback (void * handle, CNVConnectionStatus status, int error, CallbackData* cb_data) { if (error < 0) { std::cerr << "StatusCallback: " << cb_data->nv_name << ": " << CNVGetErrorDescription(error) << std::endl; } else { std::cerr << "StatusCallback: " << cb_data->nv_name << " is " << connectionStatus(status) << std::endl; } }
/// called when data has been transferred to the variable void NetShrVarInterface::dataTransferredCallback (void * handle, int error, CallbackData* cb_data) { if (error < 0) { std::cerr << "dataTransferredCallback: \"" << cb_data->nv_name << "\": " << CNVGetErrorDescription(error) << std::endl; } // else // { // std::cerr << "dataTransferredCallback: " << cb_data->nv_name << " OK " << std::endl; // } }
///---------------------------------------------------------------------------- /// HIFN Network Variable Data Transferred Callback called when written data /// HIFN is successfully received by the server. /// HIFN NOTE: This callback is called on a worker thread and not the main thread. /// HIPAR handle/Handle of the Network Variable connection /// HIPAR error/The error, if any, in transferring the Network Variable data /// HIPAR callbackData/User specified callback data ///---------------------------------------------------------------------------- static void CVICALLBACK DataTransferredCallback (void * handle, int error, void * callbackData) { if (error < 0) { SetCtrlVal (panelHandle, PANEL_CNVSTATUS, CNVGetErrorDescription(error)); } else { SetCtrlVal (panelHandle, PANEL_LED, 1); } }
/// the quality of the data in a network shared variable static std::string dataQuality(CNVDataQuality quality) { std::string res; char* description = NULL; int error = CNVGetDataQualityDescription(quality, ";", &description); if (error == 0) { res = description; CNVFreeMemory(description); } else { res = std::string("CNVGetDataQualityDescription: ") + CNVGetErrorDescription(error); } return res; }
///---------------------------------------------------------------------------- /// HIFN Network Variable Status Callback called whenever connection status changes. /// HIFN NOTE: This callback is called on a worker thread and not the main thread. /// HIPAR handle/Handle of the Network Variable connection /// HIPAR status/The new status of the Network Variable connection /// HIPAR error/The error, if any, in the Network Variable connection /// HIPAR callbackData/User specified callback data ///---------------------------------------------------------------------------- static void CVICALLBACK StatusCallback (void * handle, CNVConnectionStatus status, int error, void * callbackData) { if (error < 0) { SetCtrlVal (panelHandle, PANEL_CNVSTATUS, CNVGetErrorDescription(error)); } else { switch (status) { case CNVConnecting: SetCtrlVal (panelHandle, PANEL_CNVSTATUS, "Connecting..."); break; case CNVConnected: SetCtrlVal (panelHandle, PANEL_CNVSTATUS, "Connected"); break; case CNVDisconnected: SetCtrlVal (panelHandle, PANEL_CNVSTATUS, "Disconnected!"); break; } } }
int CVICALLBACK threadFunc (void *functionData) { char textline[1024]; volatile int stop = 0, loop = 0; double value = 0.0; CNVBufferedWriter bufferedWriter; CNVData data = 0; int error; char buffer[MAX_PATHNAME_LEN]; // wait for tread lock CmtGetLock (lock); // release the lock CmtReleaseLock (lock); status = 2; // run while loop SetCtrlVal (panelHandle, PANEL_STATUS, status); SetCtrlVal(panelHandle, PANEL_TEXTSTRING, "Nice! thread() has been started!"); Delay (1.0); error = NetworkVariablePopup (buffer); if (error < 0) { MessagePopup ("Error", GetGeneralErrorString(error)); return 0; } else if (error > 0) { SetCtrlVal (panelHandle, PANEL_NAME, buffer); SetWaitCursor (1); error = CNVCreateBufferedWriter (buffer, DataTransferredCallback, StatusCallback, 0, 10, 10000, 0, &bufferedWriter); SetWaitCursor (0); if (error < 0) { MessagePopup ("Error", CNVGetErrorDescription(error)); return 0; } else { SetCtrlVal (panelHandle, PANEL_CNVSTATUS, "Connected"); } } CNVCreateScalarDataValue (&data, CNVDouble, value); while (stop == 0) { SetCtrlVal (panelHandle, PANEL_LED, 0); GetCtrlVal (panelHandle, PANEL_STOPBUTTON, &stop); Delay (0.2); sprintf (textline, "%i, %i", loop++, stop); SetCtrlVal (panelHandle, PANEL_TEXTSTRING, textline); value = loop; CNVSetScalarDataValue (data, CNVDouble, value); CNVPutDataInBuffer (bufferedWriter, data, CNVDoNotWait); } SetCtrlVal(panelHandle, PANEL_TEXTSTRING, "Nice! thread() has been stopped!"); Delay (1.0); CNVDisposeData (data); CNVDispose (bufferedWriter); CNVFinish (); status = 3; // exit threadFunc() SetCtrlVal (panelHandle, PANEL_STATUS, status); return 0; }
static std::string ni_message(const std::string& function, int code) { return function + ": " + CNVGetErrorDescription(code); }
void NetShrVarInterface::updateParamCNV (int param_index, CNVData data, bool do_asyn_param_callbacks) { unsigned int nDims; unsigned int serverError; CNVDataType type; CNVDataQuality quality; unsigned __int64 timestamp; int year, month, day, hour, minute, good; double second; int status; unsigned short numberOfFields = 0; const char *paramName = NULL; m_driver->getParamName(param_index, ¶mName); if (data == 0) { // std::cerr << "updateParamCNV: no data for param " << paramName << std::endl; return; } status = CNVGetDataType (data, &type, &nDims); ERROR_CHECK("CNVGetDataType", status); if (type == CNVStruct) { int field = m_params[paramName]->field; status = CNVGetNumberOfStructFields(data, &numberOfFields); ERROR_CHECK("CNVGetNumberOfStructFields", status); if (numberOfFields == 0) { throw std::runtime_error("number of fields"); } if (field < 0 || field >= numberOfFields) { throw std::runtime_error("field index"); } CNVData* fields = new CNVData[numberOfFields]; status = CNVGetStructFields(data, fields, numberOfFields); ERROR_CHECK("CNVGetStructFields", status); updateParamCNV(param_index, fields[field], do_asyn_param_callbacks); delete[] fields; return; } status = CNVGetDataQuality(data, &quality); ERROR_CHECK("CNVGetDataQuality", status); status = CNVCheckDataQuality(quality, &good); ERROR_CHECK("CNVCheckDataQuality", status); status = CNVGetDataUTCTimestamp(data, ×tamp); ERROR_CHECK("CNVGetDataUTCTimestamp", status); status = CNVGetTimestampInfo(timestamp, &year, &month, &day, &hour, &minute, &second); ERROR_CHECK("CNVGetTimestampInfo", status); if (good == 0) { std::cerr << "updateParamCNV: data for param " << paramName << " is not good quality: " << dataQuality(quality) << std::endl; } switch(type) { case CNVEmpty: break; case CNVBool: updateParamCNVImpl<CNVBool>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVString: updateParamCNVImpl<CNVString>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVSingle: updateParamCNVImpl<CNVSingle>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVDouble: updateParamCNVImpl<CNVDouble>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVInt8: updateParamCNVImpl<CNVInt8>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVUInt8: updateParamCNVImpl<CNVUInt8>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVInt16: updateParamCNVImpl<CNVInt16>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVUInt16: updateParamCNVImpl<CNVUInt16>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVInt32: updateParamCNVImpl<CNVInt32>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVUInt32: updateParamCNVImpl<CNVUInt32>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVInt64: updateParamCNVImpl<CNVInt64>(param_index, data, type, nDims, do_asyn_param_callbacks); break; case CNVUInt64: updateParamCNVImpl<CNVUInt64>(param_index, data, type, nDims, do_asyn_param_callbacks); break; default: std::cerr << "updateParamCNV: unknown type " << type << " for param " << paramName << std::endl; break; } status = CNVGetDataServerError(data, &serverError); if (status == 0 && serverError != 0) { std::cerr << "updateParamCNV: Server error: " << serverError << std::endl; } else if (status < 0) { std::cerr << "updateParamCNV: CNVGetDataServerError: " << CNVGetErrorDescription(status) << std::endl; } }