cp1616_io_device_callbacks.cpp
Go to the documentation of this file.
00001 /*********************************************************************************************/
00021 #ifndef CP1616_IO_DEVICE_CALLBACKS_CPP
00022 #define CP1616_IO_DEVICE_CALLBACKS_CPP
00023 
00024 #include <cp1616/cp1616_io_device.h>
00025 #include <cp1616/cp1616_io_device_callbacks.h>
00026 
00027 namespace cp1616
00028 {
00029 namespace pnio_device_callbacks
00030 {
00031   PNIO_IOXS dataRead(
00032     PNIO_UINT32 dev_handle,
00033     PNIO_DEV_ADDR *p_addr,
00034     PNIO_UINT32 buffer_length,
00035     PNIO_UINT8 *p_buffer,
00036     PNIO_IOXS iops)
00037   {
00038     //Create CallbackHandler object to access cp1616_io_device variables
00039     Cp1616IODevice *CallbackHandler = Cp1616IODevice::getDeviceInstance();
00040 
00041     unsigned int i;
00042 
00043     PNIO_UINT32 slot_num     = p_addr->u.Geo.Slot;
00044     PNIO_UINT32 subslot_num  = p_addr->u.Geo.Subslot;
00045 
00046     ROS_DEBUG("PNIO_cbf_data_read(..., len=%u, Iops=%u) for devHandle 0x%x, slot %u, subslot %u",
00047       buffer_length, iops, dev_handle, slot_num, subslot_num);
00048 
00049     CallbackHandler->setOutputDataLength(slot_num, subslot_num, buffer_length);  //save data length (only for debugging)
00050     CallbackHandler->setOutputDataIops(slot_num, subslot_num, iops);             //provider status (of remote IO controller)
00051 
00052     if(buffer_length == 0)
00053     {
00054       ROS_INFO_STREAM(" BufLen = 0, nothing to read...");
00055       CallbackHandler->setOutputDataIocs(slot_num, subslot_num, PNIO_S_GOOD);
00056      }
00057     else if(buffer_length <= (PNIO_UINT32)NUMOF_BYTES_PER_SUBSLOT)
00058     {
00059       memcpy (&CallbackHandler->output_data_[slot_num][subslot_num][0], p_buffer, buffer_length); //Copy the data from the stack to the application buffer
00060       CallbackHandler->setOutputDataIocs(slot_num, subslot_num, PNIO_S_GOOD);                    // assume everything is ok
00061 
00062       std::cout << "OutData: [slot " << slot_num << "]: ";
00063       for(i = 0; i < buffer_length; i++)
00064       {
00065         if(i % 16 == 0 && i!=0)
00066         std::cout << std::endl;
00067 
00068         std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)p_buffer[i] << " ";
00069       }
00070 
00071       std::cout <<std::dec << std::endl;
00072     }
00073     else
00074     {
00075       ROS_ERROR("!!! PNIO_cbf_data_read: Buflen=%lu > allowed size (%u)!!! Abort reading...",
00076        (unsigned long)buffer_length, NUMOF_BYTES_PER_SUBSLOT);
00077       CallbackHandler->setOutputDataIocs(slot_num, subslot_num, PNIO_S_BAD); // set local status to bad
00078     }
00079 
00080   return(CallbackHandler->getOutputDataIocs(slot_num, subslot_num));         //consumer state (of local IO device)
00081 }
00082 
00083   PNIO_IOXS dataWrite(
00084     PNIO_UINT32 dev_handle,
00085     PNIO_DEV_ADDR *p_addr,
00086     PNIO_UINT32 buffer_length,
00087     PNIO_UINT8 *p_buffer,
00088     PNIO_IOXS iocs)
00089   {
00090     //Create CallbackHandler object to access cp1616_io_device variables
00091     Cp1616IODevice *CallbackHandler = Cp1616IODevice::getDeviceInstance();
00092 
00093     unsigned int i;
00094  
00095     PNIO_UINT32 slot_num    = p_addr->u.Geo.Slot;
00096     PNIO_UINT32 subslot_num = p_addr->u.Geo.Subslot;
00097 
00098     ROS_DEBUG("PNIO_cbf_data_write(len = %u, Iocs = %u devHandle = %u, slot = %u, subslot = %u",
00099       buffer_length, iocs, dev_handle, slot_num, subslot_num);
00100   
00101     CallbackHandler->setInputDataLength(slot_num,subslot_num,buffer_length);   //save data length (only for debugging)
00102     CallbackHandler->setInputDataIocs(slot_num, subslot_num, iocs);            //consumer status (of remote IO Controller)
00103 
00104     if(buffer_length == 0)
00105     {
00106       CallbackHandler->setInputDataIops(slot_num, subslot_num, PNIO_S_GOOD);
00107     }
00108     else if (buffer_length <= (PNIO_UINT32)NUMOF_BYTES_PER_SUBSLOT)
00109     {
00110       memcpy(p_buffer, &CallbackHandler->input_data_[slot_num][subslot_num][0], buffer_length);//copy the application data to the stack
00111       CallbackHandler->setInputDataIops(slot_num, subslot_num, PNIO_S_GOOD);        //assume everything is ok
00112 
00113       std::cout << "InData:  [slot " << slot_num << "]: ";
00114       for(i = 0; i < buffer_length; i++)
00115       {
00116         if(i%16 == 0 && i!=0)
00117         std::cout << std::endl;
00118 
00119         std::cout << "0x"<< std::hex << std::setw(2) << std::setfill('0') << (int)p_buffer[i] << " ";
00120       }
00121       std::cout << std::dec << std::endl;
00122     }
00123     else
00124     {
00125       ROS_ERROR("!!! PNIO_cbf_data_write: Buflen=%lu > allowed size (%u)!!! Abort writing..",
00126         (unsigned long)buffer_length, NUMOF_BYTES_PER_SUBSLOT);
00127 
00128       CallbackHandler->setInputDataIops(slot_num, subslot_num, PNIO_S_BAD); // set local status to bad 
00129     }
00130 
00131     return(CallbackHandler->getInputDataIops(slot_num, subslot_num));       //return local provider status
00132 }
00133 
00134   void recordWrite(
00135     PNIO_UINT32 dev_handle,
00136     PNIO_UINT32 api,
00137     PNIO_UINT16 ar_number,
00138     PNIO_UINT16 sessi,
00139     PNIO_UINT32 sequence_number,
00140     PNIO_DEV_ADDR *p_addr,
00141     PNIO_UINT32 record_index,
00142     PNIO_UINT32 *p_buffer_length,
00143     PNIO_UINT8 *p_buffer,
00144     PNIO_ERR_STAT *p_pnio_state)
00145   {
00146 
00147     PNIO_UINT8  write_rec_dummy_data[50];
00148     PNIO_UINT32 i;
00149     PNIO_UINT32 error_code = PNIO_OK;
00150 
00151     ROS_DEBUG("WRITE RECORD Request, Api=%lu Slot=%lu Subslot=%lu Index=%lu, Length=%lu, Sequence_nr=%lu",
00152       (unsigned long)api,
00153       (unsigned long)p_addr->u.Geo.Slot,
00154       (unsigned long)p_addr->u.Geo.Subslot,
00155       (unsigned long)record_index,
00156       (unsigned long)*p_buffer_length,
00157       (unsigned long)sequence_number);
00158  
00159     //check data size (accepted_data < provided_data)
00160     if(*p_buffer_length > sizeof(write_rec_dummy_data))
00161     {
00162       *p_buffer_length = sizeof(write_rec_dummy_data);
00163       ROS_WARN_STREAM("Can not write all data, not enough space...");
00164     }
00165 
00166     //copy the record data into a buffer for further use
00167     memcpy(write_rec_dummy_data,  //destination pointer for record data
00168            p_buffer,              //source pointer for record data
00169           *p_buffer_length);      //length of the accepted data
00170 
00171     ROS_INFO_STREAM("RECORD DATA written");
00172 
00173     if(error_code == PNIO_OK)
00174     {
00175       memset(p_pnio_state, 0, sizeof(*p_pnio_state));
00176       return;
00177     }
00178     else  //if an eror occured, it must be specified according to IEC 61158-6
00179     {
00180       *p_buffer_length = 0;
00181 
00182       p_pnio_state->ErrCode   = 0xdf; //IODWrites with ErrorDecode = PNIORW
00183       p_pnio_state->ErrDecode = 0x80; //PNIORW
00184       p_pnio_state->ErrCode1  = 9;    //example: Error Class 10 = application, ErrorNr 9 = "feature not supported"
00185       p_pnio_state->ErrCode2  = 0;    //not used in this case
00186       p_pnio_state->AddValue1 = 0;    //not used in this case
00187       p_pnio_state->AddValue2  =0;    //not used in this case
00188 
00189       return;
00190     }
00191   }
00192 
00193   void recordRead(
00194     PNIO_UINT32 dev_handle,
00195     PNIO_UINT32 api,
00196     PNIO_UINT16 ar_number,
00197     PNIO_UINT16 sessi,
00198     PNIO_UINT32 sequence_number,
00199     PNIO_DEV_ADDR *p_addr,
00200     PNIO_UINT32 record_index,
00201     PNIO_UINT32 *p_buffer_length,
00202     PNIO_UINT8 *p_buffer,
00203     PNIO_ERR_STAT *p_pnio_state)
00204   {
00205 
00206     PNIO_UINT32 i;
00207     PNIO_UINT32 error_code = PNIO_OK;
00208 
00209     //fill dummy buffer
00210     PNIO_UINT8 read_rec_dummy_data[] = {"Test Record"};
00211 
00212     if(*p_buffer_length > sizeof(read_rec_dummy_data))
00213       *p_buffer_length = sizeof(read_rec_dummy_data);
00214 
00215     ROS_DEBUG("READ_RECORD Request, Api=%lu Slot=%lu Subslot=%lu Index=%lu, Length=%lu, Sequence_nr=%lu",
00216       (unsigned long)api,
00217       (unsigned long)p_addr->u.Geo.Slot,
00218       (unsigned long)p_addr->u.Geo.Subslot,
00219       (unsigned long)record_index,
00220       (unsigned long)*p_buffer_length,
00221       (unsigned long)sequence_number);
00222 
00223     //copy the data to specified buffer
00224     if(*p_buffer_length < sizeof(read_rec_dummy_data))
00225       ROS_WARN_STREAM("WARNING: Can not transmit all data, buffer too small...");
00226 
00227     memcpy(p_buffer,              //destination pointer for write data
00228            read_rec_dummy_data,   //source pointer for write data
00229            *p_buffer_length);     //length of transmitted data
00230 
00231     ROS_INFO_STREAM("RECORD DATA transmitted:");
00232 
00233     if(error_code == PNIO_OK)
00234     {
00235       memset(p_pnio_state, 0, sizeof(*p_pnio_state));
00236       return;
00237     }
00238     else
00239     {
00240       *p_buffer_length=0;
00241       p_pnio_state->ErrCode   = 0xde; //IODReadRes with ErrorDecode = PNIORW
00242       p_pnio_state->ErrDecode = 0x80; //PNIORW
00243       p_pnio_state->ErrCode1  = 9;    //example: Error Class 10 = application, ErrorNr 9 = "feature not supported"
00244       p_pnio_state->ErrCode2  = 0;    //not used in this case
00245       p_pnio_state->AddValue1 = 0;    //not used in this case
00246       p_pnio_state->AddValue2 = 0;    //not used in this case
00247       return;
00248     }
00249   }
00250 
00251   void checkIndication(
00252     PNIO_UINT32 dev_handle,
00253     PNIO_UINT32 api,
00254     PNIO_UINT16 ar_number,
00255     PNIO_UINT16 session_key,
00256     PNIO_DEV_ADDR *p_addr,
00257     PNIO_UINT32 *p_mod_ident,
00258     PNIO_UINT16 *p_mod_state,
00259     PNIO_UINT32 *p_sub_ident,
00260     PNIO_UINT16 *p_sub_state)
00261   {
00262     //Create CallbackHandler object to access cp1616_io_device variables
00263     Cp1616IODevice *CallbackHandler = Cp1616IODevice::getDeviceInstance();
00264 
00265     unsigned int idx;
00266 
00267     ROS_INFO("CHECK_IND slot=%u, subslot=%u, ModId=0x%x, State(%u), SubId=%u, State (%u)",
00268       p_addr->u.Geo.Slot, p_addr->u.Geo.Subslot, *p_mod_ident, *p_mod_state, *p_sub_ident, *p_sub_state);
00269 
00270     // get the index int of our configuration 
00271     idx = CallbackHandler->GetSubmodNum(p_addr->u.Geo.Slot, p_addr->u.Geo.Subslot);
00272 
00273     /* Check the configuration sent by device against the configuration_data structure.
00274     If there is any mismatch, return error. */
00275 
00276     if((idx != -1) && ((unsigned int)CallbackHandler->p_device_data_[idx].subslot == p_addr->u.Geo.Subslot)
00277                    && (CallbackHandler->p_device_data_[idx].modId == *p_mod_ident)
00278                    && (CallbackHandler->p_device_data_[idx].subslotId == *p_sub_ident))
00279     {
00280       *p_mod_state = PNIO_MOD_STATE_PROPER_MODULE;
00281       *p_sub_state = PNIO_SUB_STATE_IDENT_OK;
00282     } 
00283     else
00284     {
00285       ROS_WARN_STREAM ("## the configuration of plugged modules is inconsistent to HWCONFIG, please check your configuration first!");
00286       *p_mod_state = PNIO_MOD_STATE_WRONG_MODULE;
00287       *p_sub_state = PNIO_SUB_STATE_IDENT_WRONG;
00288     }
00289 }
00290 
00291   void arCheckIndication(
00292           PNIO_UINT32 dev_handle,
00293           PNIO_UINT32 host_ip,
00294           PNIO_UINT16 ar_type,
00295           PNIO_UUID_TYPE ar_uuid,
00296           PNIO_UINT32 ar_properties,
00297           PNIO_UUID_TYPE cmi_obj_uuid,
00298           PNIO_UINT16 cmi_station_name_length,
00299           PNIO_UINT8 *p_cmi_station_name,
00300           PNIO_AR_TYPE *p_ar)
00301   {
00302     union
00303     {
00304       unsigned long l;
00305       unsigned char c[4];
00306     } lc;
00307 
00308     char stname[256];
00309     int  len = cmi_station_name_length < 256 ? cmi_station_name_length : 255;
00310     lc.l = host_ip;
00311     strncpy(stname, (const char *)p_cmi_station_name, len);  //copy StationName to stname
00312     stname[len] = '\0';
00313     ROS_INFO("PNIO_cbf_ar_check_ind (Station %s, IP %d.%d.%d.%d)", stname,lc.c[0], lc.c[1], lc.c[2], lc.c[3]);
00314 }
00315 
00316   void arInfoIndication(
00317           PNIO_UINT32 dev_handle,
00318           PNIO_UINT16 ar_number,
00319           PNIO_UINT16 session_key,
00320           PNIO_AR_TYPE *p_ar)
00321   {
00322     //Create CallbackHandler object to access cp1616_io_device variables
00323     Cp1616IODevice *CallbackHandler = Cp1616IODevice::getDeviceInstance();
00324 
00325     int i,j;
00326 
00327     CallbackHandler->setCpArNumber(ar_number);        //Store the AR number
00328     CallbackHandler->setCpSessionKey(session_key);    //Store the session key
00329 
00330     ROS_INFO("AR-INFO_IND new AR from PNIO controller established, SessionKey %x", session_key);
00331      
00332     // set local provider status preset values for all input/output slots
00333     // set local consumer status for all output slots
00334     for(i = 0; i < DEVICE_DATA_ENTRIES ; i++)
00335     {
00336       for(j = 0; j < 1 /*g_device_data[i].maxSubslots*/; j++)
00337       {
00338         //set local provider state = GOOD for input data
00339         if(i == 0) {
00340             if(CallbackHandler->p_device_data_[i].modState == 1) // plugged 
00341           {
00342             CallbackHandler->setInputDataIops(i, j, PNIO_S_GOOD);
00343             CallbackHandler->setOutputDataIocs(i,j,PNIO_S_GOOD);
00344           }
00345           else
00346           {
00347             CallbackHandler->setInputDataIops(i, j, PNIO_S_BAD);
00348             CallbackHandler->setOutputDataIocs(i,j,PNIO_S_BAD);
00349           }
00350         }
00351         else
00352         {
00353           if((CallbackHandler->p_device_data_[i].modState == 1)
00354               && (CallbackHandler->p_device_data_[i+j].subState == 1)) // plugged 
00355           {
00356             CallbackHandler->setInputDataIops(i, j, PNIO_S_GOOD);
00357             CallbackHandler->setOutputDataIocs(i,j,PNIO_S_GOOD);
00358           }
00359           else
00360           {
00361             CallbackHandler->setInputDataIops(i, j, PNIO_S_BAD);
00362             CallbackHandler->setOutputDataIocs(i,j,PNIO_S_BAD);
00363           }
00364         }
00365       }
00366     }
00367 
00368     CallbackHandler->setArInfoIndFlag(1);
00369   }
00370 
00371   void arIndataIndication(
00372           PNIO_UINT32     dev_handle,
00373           PNIO_UINT16     ar_number,
00374           PNIO_UINT16     session_key)
00375   {
00376     //Create CallbackHandler object to access cp1616_io_device variables
00377     Cp1616IODevice *CallbackHandler = Cp1616IODevice::getDeviceInstance();
00378 
00379     CallbackHandler->setIndataIndFlag(1);
00380   }
00381 
00382   void arAbortIndication(
00383     PNIO_UINT32 dev_handle,
00384     PNIO_UINT16 ar_number,
00385     PNIO_UINT16 session_key,
00386     PNIO_AR_REASON reason_code)
00387   {
00388     // AR abort after ArInData-indication
00389     ROS_INFO("AR ABORT indication, ArNumber = %x, Reason = %x", ar_number, reason_code);
00390   }
00391 
00392   void arOfflineIndication(
00393     PNIO_UINT32 dev_handle,
00394     PNIO_UINT16 ar_number,
00395     PNIO_UINT16 session_key,
00396     PNIO_AR_REASON reason_code)
00397   {
00398     //Create CallbackHandler object to access cp1616_io_device variables
00399     Cp1616IODevice *CallbackHandler = Cp1616IODevice::getDeviceInstance();
00400 
00401     ROS_INFO("AR Offline indication, ArNumber = %x, Reason = %x", ar_number, reason_code);
00402     CallbackHandler->setOfflineIndFlag(1);
00403   }
00404 
00405   void prmEndIndication(
00406     PNIO_UINT32 dev_handle,
00407     PNIO_UINT16 ar_number,
00408     PNIO_UINT16 session_key,
00409     PNIO_UINT32 api,
00410     PNIO_UINT16 slot_number,
00411     PNIO_UINT16 subslot_number)
00412   {
00413  
00414     //Create CallbackHandler object to access cp1616_io_device variables
00415     Cp1616IODevice *CallbackHandler = Cp1616IODevice::getDeviceInstance();
00416 
00417     unsigned int i = 0;
00418 
00419     // Wait (MAX_COUNT x 0.1s) for PNIO_cbf_ar_info_ind() Callbacks
00420     while (CallbackHandler->getArInfoIndFlag() == 0)
00421     {
00422       if (i == MAX_AR_INFO_COUNT)
00423       {
00424         ROS_INFO_STREAM("No PNIOCbfArInfoInd event recieved");
00425         return;
00426       }
00427       i++;
00428       usleep(100000);
00429     }
00430     ROS_INFO_STREAM("End of parametrizing phase - Application ready");
00431 
00432     CallbackHandler->setPrmEndIndFlag(1);
00433   }
00434 
00435   void cpStopRequest(
00436     PNIO_UINT32 dev_handle)
00437   {
00438     ROS_INFO_STREAM("PNIOCbfCpStopReq called");
00439   }
00440 
00441   void deviceStopped(
00442     PNIO_UINT32 dev_handle,
00443     PNIO_UINT32 reserved)
00444   {
00445     ROS_INFO_STREAM("IO Device stopped");
00446   }
00447 
00448   void requestDone(
00449     PNIO_UINT32 dev_handle,
00450     PNIO_UINT32 user_handle,
00451     PNIO_UINT32 status,
00452     PNIO_ERR_STAT *p_pnio_state)
00453   {
00454     ROS_INFO_STREAM("PNIOCbfReqDone not supported");
00455   }
00456 
00457   void apduStatusIndication(
00458     PNIO_UINT32 dev_handle,
00459     PNIO_UINT16 ar_number,
00460     PNIO_UINT16 session_key,
00461     PNIO_APDU_STATUS_IND apdu_status)
00462   {
00463     ROS_INFO_STREAM("PNIOCbfApduStatusInd not supported");
00464   }
00465   
00466 } //pnio_device_callbacks
00467 } //cp1616
00468 
00469 #endif //CP1616_IO_DEVICE_CALLBACKS_CPP


cp1616
Author(s):
autogenerated on Fri Aug 28 2015 13:08:36