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
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);
00050 CallbackHandler->setOutputDataIops(slot_num, subslot_num, iops);
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);
00060 CallbackHandler->setOutputDataIocs(slot_num, subslot_num, PNIO_S_GOOD);
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);
00078 }
00079
00080 return(CallbackHandler->getOutputDataIocs(slot_num, subslot_num));
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
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);
00102 CallbackHandler->setInputDataIocs(slot_num, subslot_num, iocs);
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);
00111 CallbackHandler->setInputDataIops(slot_num, subslot_num, PNIO_S_GOOD);
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);
00129 }
00130
00131 return(CallbackHandler->getInputDataIops(slot_num, subslot_num));
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
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
00167 memcpy(write_rec_dummy_data,
00168 p_buffer,
00169 *p_buffer_length);
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
00179 {
00180 *p_buffer_length = 0;
00181
00182 p_pnio_state->ErrCode = 0xdf;
00183 p_pnio_state->ErrDecode = 0x80;
00184 p_pnio_state->ErrCode1 = 9;
00185 p_pnio_state->ErrCode2 = 0;
00186 p_pnio_state->AddValue1 = 0;
00187 p_pnio_state->AddValue2 =0;
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
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
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,
00228 read_rec_dummy_data,
00229 *p_buffer_length);
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;
00242 p_pnio_state->ErrDecode = 0x80;
00243 p_pnio_state->ErrCode1 = 9;
00244 p_pnio_state->ErrCode2 = 0;
00245 p_pnio_state->AddValue1 = 0;
00246 p_pnio_state->AddValue2 = 0;
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
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
00271 idx = CallbackHandler->GetSubmodNum(p_addr->u.Geo.Slot, p_addr->u.Geo.Subslot);
00272
00273
00274
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);
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
00323 Cp1616IODevice *CallbackHandler = Cp1616IODevice::getDeviceInstance();
00324
00325 int i,j;
00326
00327 CallbackHandler->setCpArNumber(ar_number);
00328 CallbackHandler->setCpSessionKey(session_key);
00329
00330 ROS_INFO("AR-INFO_IND new AR from PNIO controller established, SessionKey %x", session_key);
00331
00332
00333
00334 for(i = 0; i < DEVICE_DATA_ENTRIES ; i++)
00335 {
00336 for(j = 0; j < 1 ; j++)
00337 {
00338
00339 if(i == 0) {
00340 if(CallbackHandler->p_device_data_[i].modState == 1)
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))
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
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
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
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
00415 Cp1616IODevice *CallbackHandler = Cp1616IODevice::getDeviceInstance();
00416
00417 unsigned int i = 0;
00418
00419
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 }
00467 }
00468
00469 #endif //CP1616_IO_DEVICE_CALLBACKS_CPP