00001 #include "Simulator.h"
00002
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <unistd.h>
00006 #include <errno.h>
00007 #include <fcntl.h>
00008 #include <poll.h>
00009 #include <math.h>
00010 #include <string.h>
00011
00012
00013 #include <time.h>
00014 #include <sys/time.h>
00015 #include <sys/timex.h>
00016
00017 #include "roc/Message.h"
00018
00019 struct sc_config gC;
00020
00021 struct sc_data gD;
00022
00023 double get_clock()
00024 {
00025 static double firsttm = 0.;
00026
00027
00028
00029 struct timeval tv;
00030 struct timezone tz;
00031 if (gettimeofday(&tv, &tz)<0) {
00032 int k = errno;
00033 printf("problem to get time err = %d %d %d\n", k, EFAULT, EINVAL);
00034 }
00035 double tttt = 1.*tv.tv_sec + tv.tv_usec * 1e-6;
00036
00037 if (firsttm == 0.) firsttm = tttt;
00038
00039
00040
00041
00042
00043
00044
00045
00046 return tttt - firsttm;
00047 }
00048
00049 bool SetNonBlockSocket(int fd)
00050 {
00051 int opts = fcntl(fd, F_GETFL);
00052 if (opts < 0) {
00053 printf(("fcntl(F_GETFL) failed\n"));
00054 return false;
00055 }
00056 opts = (opts | O_NONBLOCK);
00057 if (fcntl(fd, F_SETFL,opts) < 0) {
00058 printf(("fcntl(F_SETFL) failed\n"));
00059 return false;
00060 }
00061 return true;
00062 }
00063
00064 int StartUdp(int& portnum, int portmin = 0, int portmax = 0)
00065 {
00066
00067 int fd = socket(PF_INET, SOCK_DGRAM, 0);
00068 if (fd<0) return -1;
00069
00070 struct sockaddr_in m_addr;
00071 int numtests = 1;
00072 if ((portmin>0) && (portmax>0) && (portmin<=portmax)) numtests+=(portmax-portmin+1);
00073
00074 if (SetNonBlockSocket(fd))
00075 for(int ntest=0;ntest<numtests;ntest++) {
00076 if ((ntest==0) && (portnum<0)) continue;
00077 if (ntest>0) portnum = portmin - 1 + ntest;
00078
00079 memset(&m_addr, 0, sizeof(m_addr));
00080 m_addr.sin_family = AF_INET;
00081 m_addr.sin_port = htons(portnum);
00082
00083 if (!bind(fd, (struct sockaddr*)&m_addr, sizeof(m_addr))) return fd;
00084 }
00085
00086 close(fd);
00087 return -1;
00088 }
00089
00090 const char* IpToStr(in_addr_t src_ip)
00091 {
00092 static char buf[200];
00093 snprintf(buf, sizeof(buf), "%u.%u.%u.%u",
00094 src_ip & 0xff, (src_ip >> 8) & 0xff,
00095 (src_ip >> 16) & 0xff, (src_ip >> 24) & 0xff);
00096 return buf;
00097 }
00098
00099
00100 UdpSimulator::UdpSimulator(int rocid, int syncscale, int period0, int period1, int ctrlport)
00101 {
00102 printf("Starting ROC Simulator...\n");
00103 memset(nxRegister, 0, sizeof(nxRegister));
00104 nxRegister[0] = ROC_SIMULATOR_HW_VERSION;
00105
00106 memset(gpioRegs, 0, sizeof(gpioRegs));
00107
00108 syncMDelay() = syncscale;
00109 gpioConfig() = (3 << (base::SYNC_S0*4));
00110
00111 periodAUX0 = 2000000;
00112 if (period0>=0) gpioConfig() |= (3 << (base::AUX0*4));
00113 if (period0>0) periodAUX0 = (unsigned) period0;
00114
00115 periodAUX1 = 20000;
00116 if (period1>=0) gpioConfig() |= (3 << (base::AUX1*4));
00117 if (period1>0) periodAUX1 = (unsigned) period1;
00118
00119 resetSimulator();
00120
00121 recvDataSize = 0;
00122 sendDataSize = 0;
00123 takeDataSize = 0;
00124 memset(&fStat, 0, sizeof(fStat));
00125
00126 setLostRates(0., 0.);
00127
00128 srand(3442143);
00129
00130 gC.ctrlPort = ROC_DEFAULT_CTRLPORT;
00131 gC.dataPort = ROC_DEFAULT_DATAPORT;
00132
00133 if (ctrlport>1000) {
00134 gC.ctrlPort = ctrlport;
00135 gC.dataPort = ctrlport-1;
00136 }
00137
00138 gC.rocNumber = rocid;
00139 gC.flushTimeout = 1000;
00140
00141 gD.high_water = 2000;
00142 gD.low_water = 50;
00143
00144 gD.headid = 0;
00145 gD.send_limit = 0;
00146 gD.resend_size = 0;
00147 gD.last_req_pkt_id = 0;
00148
00149 gD.masterConnected = false;
00150 gD.masterDataPort = 0;
00151 gD.masterPort = 0;
00152 gD.masterIp = 0;
00153 gD.lastMasterPacketId = 0;
00154 gD.master_retry_buf_rawsize = 0;
00155
00156 gD.controlPort = 0;
00157 gD.controlIp = 0;
00158 gD.lastControlPacketId = 0;
00159 gD.control_retry_buf_rawsize = 0;
00160
00161 gD.controlLocked = 0;
00162 gD.lockedTime = get_clock();
00163
00164 gD.daqState = 0;
00165 gD.data_taking_on = false;
00166 gD.lastMasterTime = get_clock();
00167
00168 for (int n=0;n<ROC_CMD_LST_SIZE/4;n++)
00169 gD.cmdsList[n] = 0;
00170
00171 for (int n=0;n<ROC_CMD_LST_NUMBER;n++) {
00172 int aa = n * ROC_CMD_LST_SIZE / 4 / ROC_CMD_LST_NUMBER;
00173
00174 if (n==0) {
00175 gD.cmdsList[aa++] = ROC_CMD_LST_PUT | ROC_NX_FIFO_RESET;
00176 gD.cmdsList[aa++] = 1;
00177 gD.cmdsList[aa++] = ROC_CMD_LST_PUT | ROC_NX_FIFO_RESET;
00178 gD.cmdsList[aa++] = 0;
00179 gD.cmdsList[aa++] = ROC_CMD_LST_PUT | ROC_ETH_START_DAQ;
00180 gD.cmdsList[aa++] = 1;
00181 } else
00182 if (n==1) {
00183 gD.cmdsList[aa++] = ROC_CMD_LST_PUT | ROC_ETH_STOP_DAQ;
00184 gD.cmdsList[aa++] = 1;
00185 }
00186
00187 gD.cmdsList[aa++] = ROC_CMD_LST_PUT | ROC_CMD_LST_ACTIVE;
00188 gD.cmdsList[aa++] = 0;
00189 }
00190
00191 gD.cmdListPtr = ROC_CMD_LST_SIZE / 4;
00192
00193
00194 s_data = 0;
00195 s_ctrl = 0;
00196 }
00197
00198 UdpSimulator::~UdpSimulator()
00199 {
00200
00201 close(s_data);
00202 close(s_ctrl);
00203 }
00204
00205 void UdpSimulator::resetSimulator()
00206 {
00207
00208
00209
00210 uint64_t first_stamp = 0;
00211
00212 nextEventNumber = 0;
00213 clockScrewUp = 1. + gC.rocNumber / 1000.;
00214 nextTimeHit = first_stamp + 5674;
00215 nextHitCounter = 1;
00216 nextTimeNoise = first_stamp + 3456;
00217 nextTimeSync = first_stamp + 0x345;
00218 nextTimeAUX0 = first_stamp + 0x500 + periodAUX0;
00219 nextTimeAUX1 = first_stamp + 0x764 + periodAUX1;
00220 nextAUX0Falling = true;
00221 nextAUX1Falling = true;
00222 lastEpoch = (first_stamp >> 14) - 1;
00223 nextSyncEvent = 0;
00224 }
00225
00226
00227 bool UdpSimulator::doRecvLost()
00228 {
00229 totalRecvCounter++;
00230
00231 if ((recvLostRate <=0.) || (recvLostRate >=1)) return false;
00232
00233 if (recvLostCounter>0) {
00234 --recvLostCounter;
00235 if (recvLostCounter==0) totalRecvLosts++;
00236 return (recvLostCounter==0);
00237 }
00238
00239 recvLostCounter = 1 + int (2. * rand() / RAND_MAX / recvLostRate);
00240
00241 return false;
00242 }
00243
00244
00245 bool UdpSimulator::doSendLost()
00246 {
00247 totalSendCounter++;
00248
00249 if ((sendLostRate <=0.) || (sendLostRate >=1)) return false;
00250
00251 if (sendLostCounter>0) {
00252 sendLostCounter--;
00253 if (sendLostCounter==0) totalSendLosts++;
00254 return sendLostCounter==0;
00255 }
00256
00257 sendLostCounter = 1 + int (2. * rand() / RAND_MAX / sendLostRate);
00258
00259 return false;
00260 }
00261
00262 void UdpSimulator::setLostRates(double recv, double send)
00263 {
00264 recvLostRate = recv;
00265 sendLostRate = send;
00266
00267 recvLostCounter = 0;
00268 sendLostCounter = 0;
00269
00270 totalSendCounter = 0; totalSendLosts = 0;
00271 totalRecvCounter = 0; totalRecvLosts = 0;
00272 }
00273
00274 bool UdpSimulator::initNewSockets()
00275 {
00276 int portnum = gC.ctrlPort;
00277
00278 s_ctrl = StartUdp(portnum);
00279 if (s_ctrl<=0) {
00280 printf("Cannot start control port %d\n", portnum);
00281 return false;
00282 }
00283
00284 portnum = gC.dataPort;
00285 s_data = StartUdp(portnum, portnum, portnum+100);
00286 if (s_data<=0) {
00287 printf("Cannot start data port %d\n", portnum);
00288 return false;
00289 }
00290 gC.dataPort = portnum;
00291
00292 printf("New ctrl port %d data port %d\n", gC.ctrlPort, gC.dataPort);
00293
00294 return true;
00295 }
00296
00297 void UdpSimulator::dispatchNewSockets(int tmout)
00298 {
00299 struct pollfd fds[2];
00300 fds[0].fd = s_ctrl;
00301 fds[0].events = POLLIN;
00302 fds[0].revents = 0;
00303 fds[1].fd = s_data;
00304 fds[1].events = POLLIN;
00305 fds[1].revents = 0;
00306
00307 int res = poll(fds, 2, tmout);
00308
00309 if (res==0) return;
00310
00311 struct sockaddr from;
00312 socklen_t fromlen;
00313
00314 char recvbuf[2000];
00315
00316 for (int n=0;n<2;n++) {
00317 if ((fds[n].revents & POLLIN) == 0) continue;
00318
00319 res = recvfrom(n==0 ? s_ctrl : s_data, recvbuf, sizeof(recvbuf), MSG_DONTWAIT, &from, &fromlen);
00320
00321 if (res<=0)
00322 printf("fail by receiving from %s socket res = %d err = %d socket = %d\n", (n==0 ? "ctrl" : "data"), res, errno, (n==0 ? s_ctrl : s_data));
00323 else
00324 OnRawData(n, recvbuf, res, &from, fromlen);
00325 }
00326 }
00327
00328 #define NODE_FORBIDDEN 0
00329 #define NODE_MASTER 1
00330 #define NODE_CONTROL 2
00331 #define NODE_OBSERVER 3
00332 #define NODE_SKIP 4
00333
00334
00335 int UdpSimulator::checkCtrlOperationAllowed(roc::UdpMessageFull* pkt, in_addr_t src_ip, int src_port)
00336 {
00337 bool ismaster = (gD.masterIp == src_ip) && (gD.masterPort == src_port);
00338 bool iscontrol = (gD.controlIp == src_ip) && (gD.controlPort == src_port);
00339
00340 if ((pkt->tag == ROC_POKE) && (pkt->address == ROC_ETH_MASTER_LOGIN)) {
00341
00342 if (pkt->value==0) {
00343 if (gD.masterConnected && !ismaster) {
00344 printf("Master already connected\n");
00345 return NODE_FORBIDDEN;
00346 }
00347
00348 if (iscontrol) {
00349 gD.controlIp = 0;
00350 gD.controlPort = 0;
00351 iscontrol = false;
00352 }
00353
00354 if (!ismaster) {
00355 gD.masterIp = src_ip;
00356 gD.masterPort = src_port;
00357
00358 gD.masterConnected = true;
00359 ismaster = true;
00360 gD.lastMasterPacketId = 0;
00361
00362 printf("Master is %s : %d\n", IpToStr(src_ip), src_port);
00363 }
00364 } else
00365 if (pkt->value==1) {
00366 if (gD.controlConnected && !iscontrol) {
00367 printf("Control already connected\n");
00368 return NODE_FORBIDDEN;
00369 }
00370
00371 if (ismaster) {
00372 gD.masterIp = 0;
00373 gD.masterPort = 0;
00374 ismaster = false;
00375 }
00376
00377 if (!iscontrol) {
00378 gD.controlIp = src_ip;
00379 gD.controlPort = src_port;
00380
00381 gD.controlConnected = true;
00382 iscontrol = true;
00383 gD.lastControlPacketId = 0;
00384
00385 printf("Control is %s : %d\n", IpToStr(src_ip), src_port);
00386 }
00387 } else
00388 return NODE_OBSERVER;
00389 }
00390
00391 if (gD.controlLocked) {
00392 if (((gD.controlLocked==1) && ismaster) || ((gD.controlLocked==2) && iscontrol)) {
00393
00394 } else
00395 return NODE_SKIP;
00396 }
00397
00398 if (ismaster) {
00399 gD.masterConnected = true;
00400 gD.lastMasterTime = get_clock();
00401 return NODE_MASTER;
00402 }
00403
00404 if (iscontrol) {
00405 gD.controlConnected = true;
00406 gD.lastControlTime = get_clock();
00407 return NODE_CONTROL;
00408 }
00409
00410
00411 if (pkt->tag == ROC_PEEK) return NODE_OBSERVER;
00412
00413
00414 return NODE_FORBIDDEN;
00415 }
00416
00417 void UdpSimulator::OnRawData(int number, const char* buf, int datalen, struct sockaddr* sa_from, socklen_t sa_len)
00418 {
00419 if (sa_len != sizeof(struct sockaddr_in)) return;
00420
00421 if (doRecvLost()) return;
00422
00423 recvDataSize += datalen;
00424
00425
00426
00427
00428
00429
00430 struct sockaddr_in sa;
00431 memcpy(&sa, sa_from, sa_len);
00432 in_addr_t src_ip;
00433 memcpy(&src_ip, &sa.sin_addr, 4);
00434
00435 if (src_ip == 0) {
00436 printf("Dummy source IP address - ignore\n");
00437 return;
00438 }
00439
00440 int src_port = ntohs(sa.sin_port);
00441
00442 if (number==0) {
00443
00444 roc::UdpMessageFull* pkt = (roc::UdpMessageFull*) buf;
00445
00446 if (ntohl(pkt->password) != ROC_PASSWORD) return;
00447
00448 pkt->address = ntohl(pkt->address);
00449 pkt->value = ntohl(pkt->value);
00450
00451 int nodekind = checkCtrlOperationAllowed(pkt, src_ip, src_port);
00452
00453
00454 if (nodekind==NODE_SKIP) return;
00455
00456 int rawdatasize = 0;
00457
00458 if (nodekind == NODE_FORBIDDEN) {
00459
00460
00461 pkt->value = 8;
00462 } else
00463 if ((nodekind==NODE_MASTER) && (pkt->id == gD.lastMasterPacketId)) {
00464
00465 rawdatasize = gD.master_retry_buf_rawsize;
00466 memcpy(pkt->rawdata, gD.master_retry_buf, rawdatasize);
00467 printf("!!! resend master packet %u!!!\n", (unsigned) ntohl(pkt->id));
00468 } else
00469 if ((nodekind==NODE_CONTROL) && (pkt->id == gD.lastControlPacketId)) {
00470
00471 rawdatasize = gD.control_retry_buf_rawsize;
00472 memcpy(pkt->rawdata, gD.control_retry_buf, rawdatasize);
00473 printf("!!! resend control packet %u!!!\n", (unsigned) ntohl(pkt->id));
00474 } else
00475 switch(pkt->tag) {
00476 case ROC_PEEK:
00477 pkt->address = GetReg(nodekind, pkt->address, &pkt->value, pkt->rawdata, &rawdatasize);
00478 break;
00479
00480 case ROC_POKE:
00481 pkt->value = PutReg(nodekind, pkt->address, pkt->value, pkt->rawdata);
00482 break;
00483
00484 case ROC_NOPER:
00485
00486
00487
00488 if (pkt->value == 1) {
00489 printf("LOCK control\n");
00490 if (nodekind==NODE_MASTER) gD.controlLocked = 1; else
00491 if (nodekind==NODE_CONTROL) gD.controlLocked = 2;
00492 gD.lockedTime = get_clock();
00493 } else
00494 if (gD.controlLocked) {
00495 printf("UNLOCK control\n");
00496 gD.controlLocked = 0;
00497 gD.lockedTime = 0;
00498 }
00499
00500 pkt->value = NOper(nodekind, pkt->address, (uint32_t*) pkt->rawdata);
00501 rawdatasize = pkt->address * 8;
00502 break;
00503 }
00504
00505 pkt->address = htonl(pkt->address);
00506 pkt->value = htonl(pkt->value);
00507
00508 if (!doSendLost()) {
00509 sendto(s_ctrl, (char*)pkt, sizeof(roc::UdpMessage) + rawdatasize, MSG_DONTWAIT, sa_from, sa_len);
00510 sendDataSize += sizeof(roc::UdpMessage) + rawdatasize;
00511 }
00512
00513 if ((nodekind==NODE_MASTER) && (pkt->id != gD.lastMasterPacketId)) {
00514 gD.lastMasterPacketId = pkt->id;
00515 memcpy(gD.master_retry_buf, pkt->rawdata, rawdatasize);
00516 gD.master_retry_buf_rawsize = rawdatasize;
00517 } else
00518 if ((nodekind==NODE_CONTROL) && (pkt->id != gD.lastControlPacketId)) {
00519 gD.lastControlPacketId = pkt->id;
00520 memcpy(gD.control_retry_buf, pkt->rawdata, rawdatasize);
00521 gD.control_retry_buf_rawsize = rawdatasize;
00522 }
00523
00524 } else {
00525 roc::UdpDataRequestFull* pkt = (roc::UdpDataRequestFull*) buf;
00526
00527 if (ntohl(pkt->password) != ROC_PASSWORD) return;
00528
00529 gD.lastMasterTime = get_clock();
00530
00531 pkt->reqpktid = ntohl(pkt->reqpktid);
00532 pkt->frontpktid = ntohl(pkt->frontpktid);
00533 pkt->tailpktid = ntohl(pkt->tailpktid);
00534 pkt->numresend = ntohl(pkt->numresend);
00535
00536 for (unsigned n=0; n<pkt->numresend; n++)
00537 pkt->resend[n] = ntohl(pkt->resend[n]);
00538
00539 memcpy(&gD.masterDataAddr, sa_from, sa_len);
00540
00541 processDataRequest(pkt);
00542 }
00543 }
00544
00545 uint32_t UdpSimulator::GetReg(int nodekind, uint32_t addr, uint32_t *retVal, void* rawdata, int* rawdatasize)
00546 {
00547 switch (addr) {
00548 case ROC_ETH_SWV:
00549 *retVal = ROC_SIMULATOR_SW_VERSION;
00550 return 0;
00551 case ROC_HWV:
00552 *retVal = ROC_SIMULATOR_HW_VERSION;
00553 return 0;
00554 case ROC_ETH_HWV:
00555 *retVal = ROC_SIMULATOR_HW_VERSION;
00556 return 0;
00557 case ROC_FPGA_TYPE:
00558 *retVal = ROC_SIMULATOR_FPGA_TYPE;
00559 return 0;
00560 case ROC_SVN_REVISION:
00561 *retVal = 1;
00562 return 0;
00563 case ROC_BUILD_TIME:
00564 *retVal = 41*3600*24*365;
00565 return 0;
00566 case ROC_ROCID:
00567 *retVal = gC.rocNumber;
00568 return 0;
00569 case ROC_TYPE:
00570 *retVal = 0x10002;
00571 return 0;
00572 case ROC_ETH_LOWWATER:
00573 *retVal = gD.low_water;
00574 return 0;
00575 case ROC_ETH_HIGHWATER:
00576 *retVal = gD.high_water;
00577 return 0;
00578 case ROC_ETH_DATAPORT:
00579 *retVal = gC.dataPort;
00580 return 0;
00581 case ROC_ETH_STATBLOCK: {
00582 if ((rawdata==0) || (rawdatasize==0)) return 2;
00583 roc::BoardStatistic* stat = (roc::BoardStatistic*) rawdata;
00584 stat->daqState = htonl(gD.daqState);
00585 stat->dataRate = htonl(fStat.dataRate);
00586 stat->sendRate = htonl(fStat.sendRate);
00587 stat->recvRate = htonl(fStat.recvRate);
00588 stat->nopRate = htonl(0);
00589 stat->frameRate = htonl(0);
00590 stat->takePerf = htonl(0);
00591 stat->dispPerf = htonl(0);
00592 stat->sendPerf = htonl(0);
00593
00594 *rawdatasize = sizeof(roc::BoardStatistic);
00595 return 0;
00596 }
00597 case ROC_NX_I2C_DATA:
00598 case ROC_NX_I2C_SLAVEADDR:
00599 case ROC_NX_I2C_ERROR:
00600 return 0;
00601
00602 default:
00603 if ((addr>=ROC_CMD_LST_MEM) && (addr<ROC_CMD_LST_MEM + ROC_CMD_LST_SIZE)) {
00604 if(addr % 4) return 2;
00605 addr = (addr - ROC_CMD_LST_MEM) / 4;
00606 *retVal = gD.cmdsList[addr];
00607 return 0;
00608 } else
00609 if ((addr>=ROC_NX_HWV) && (addr<ROC_NX_HWV + NX_REG_SIZE*4)) {
00610 *retVal = nxRegister[(addr-ROC_NX_HWV)/4];
00611 return 0;
00612 } else
00613 if ((addr>=base::GPIO_CONFIG) && (addr < base::GPIO_CONFIG + GPIO_REG_SIZE*4)) {
00614 *retVal = gpioRegs[(addr - base::GPIO_CONFIG)/4];
00615 return 0;
00616 } else {
00617 printf("Unknown register 0x%x\n", addr);
00618 }
00619 break;
00620 }
00621
00622 return 2;
00623 }
00624
00625 uint32_t UdpSimulator::PutReg(int nodekind, uint32_t addr, uint32_t val, uint8_t* rawdata)
00626 {
00627 printf("Roc:%u Put 0x%04x = 0x%04x\n", gC.rocNumber, addr, val);
00628
00629 switch (addr) {
00630 case ROC_ETH_START_DAQ:
00631 printf("Roc:%u Starting DAQ ...\n", gC.rocNumber);
00632 gD.buf.clear();
00633 gD.send_limit = 0;
00634 gD.headid = 0;
00635 gD.resend_size = 0;
00636 gD.last_req_pkt_id = 0;
00637 gD.next_send_id = 0;
00638 gD.data_taking_on = true;
00639 gD.lastFlushTime = get_clock();
00640
00641 gD.droppkt_id = (sendLostRate <=0.) ? 0 - 1 : gD.headid;
00642 makeSysMessage(roc::SYSMSG_DAQ_START);
00643 gD.daqState = 1;
00644 return 0;
00645 case ROC_ETH_SUSPEND_DAQ:
00646 printf("Roc:%u DAQ suspended.\n", gC.rocNumber);
00647
00648 gD.droppkt_id = (sendLostRate <=0.) ? 0 - 1 : gD.headid;
00649
00650
00651 makeSysMessage(roc::SYSMSG_DAQ_FINISH);
00652 gD.daqState = 2;
00653 gD.data_taking_on = false;
00654 return 0;
00655 case ROC_ETH_STOP_DAQ:
00656 printf("Roc:%u DAQ stopped.\n", gC.rocNumber);
00657 gD.daqState = 0;
00658 gD.buf.clear();
00659 gD.send_limit = 0;
00660 gD.headid = 0;
00661 gD.data_taking_on = false;
00662 return 0;
00663 case ROC_ROCID:
00664 printf("Set ROC id to %d.\n",val);
00665 gC.rocNumber = val;
00666 return 0;
00667 case ROC_ETH_MASTER_LOGIN:
00668 if (nodekind==NODE_MASTER) {
00669 printf("Master login & simulator reset.\n");
00670 resetSimulator();
00671 }
00672 return 0;
00673
00674 case ROC_ETH_MASTER_LOGOUT:
00675 if (nodekind==NODE_MASTER) {
00676 printf("Master is logout.\n");
00677 gD.masterConnected = false;
00678 gD.daqState = 0;
00679 totalSendLosts = 0;
00680 totalSendCounter = 0;
00681 totalRecvLosts = 0;
00682 totalRecvCounter = 0;
00683 gD.masterIp = 0;
00684 gD.masterPort = 0;
00685 gD.lastMasterPacketId = 0;
00686 if (gD.controlLocked == 1) gD.controlLocked = 0;
00687 } else
00688 if (nodekind==NODE_CONTROL) {
00689 printf("Controller is logout.\n");
00690 gD.controlConnected = false;
00691 gD.controlPort = 0;
00692 gD.controlIp = 0;
00693 gD.lastControlPacketId = 0;
00694 if (gD.controlLocked == 2) gD.controlLocked = 0;
00695 }
00696 return 0;
00697
00698 case ROC_ETH_LOWWATER:
00699 gD.low_water = val;
00700 return 0;
00701
00702 case ROC_ETH_HIGHWATER:
00703 gD.high_water = val;
00704 return 0;
00705
00706 case ROC_ETH_MASTER_DATAPORT:
00707 if (nodekind != NODE_MASTER) {
00708 printf("ERROR! Cannot change master data port from controller.\n");
00709 return 3;
00710 }
00711 gD.masterDataPort = val;
00712 printf("Set Target data port to (%d).\n",val);
00713 return 0;
00714 case ROC_NX_FIFO_RESET:
00715 return 0;
00716 case ROC_ETH_BUFFER_FLUSH_TIMER:
00717 gC.flushTimeout = val;
00718 return 0;
00719 case ROC_ETH_CONSOLE_OUTPUT:
00720 return 0;
00721 case ROC_ETH_CONSOLE_CMD:
00722 printf("Execute console command %s.\n", rawdata);
00723 return 0;
00724 case ROC_NX_NXACTIVE:
00725 case ROC_ETH_OCM:
00726 return 0;
00727
00728 case ROC_NX_I2C_DATA:
00729 case ROC_NX_I2C_RESET:
00730 case ROC_NX_I2C_REGRESET:
00731 case ROC_NX_I2C_SLAVEADDR:
00732 case ROC_NX_I2C_REGISTER:
00733 case ROC_NX_I2C_SWITCH:
00734 return 0;
00735
00736 case ROC_ADDSYSMSG:
00737 if (gD.data_taking_on)
00738 makeSysMessage(roc::SYSMSG_USER, val);
00739 return 0;
00740
00741 case ROC_CMD_LST_ACTIVE:
00742 gD.cmdListPtr = ROC_CMD_LST_SIZE / 4;
00743 return 0;
00744
00745 case ROC_CMD_LST_NR:
00746
00747 gD.cmdListPtr = (val % ROC_CMD_LST_NUMBER) * ROC_CMD_LST_SIZE / ROC_CMD_LST_NUMBER / 4;
00748 return 0;
00749
00750 case ROC_ETH_DLM:
00751
00752 if (val>=8)
00753 gD.cmdListPtr = ((val-8) % ROC_CMD_LST_NUMBER) * ROC_CMD_LST_SIZE / ROC_CMD_LST_NUMBER / 4;
00754 return 0;
00755
00756 default:
00757 if ((addr>=ROC_CMD_LST_MEM) && (addr<ROC_CMD_LST_MEM + ROC_CMD_LST_SIZE)) {
00758 if(addr % 4) return 2;
00759 addr = (addr - ROC_CMD_LST_MEM) / 4;
00760 gD.cmdsList[addr] = val;
00761 return 0;
00762 } else
00763 if ((addr>=ROC_NX_HWV) && (addr < ROC_NX_HWV + NX_REG_SIZE*4)) {
00764 nxRegister[(addr-ROC_NX_HWV)/4] = val;
00765 return 0;
00766 } else
00767 if ((addr>=base::GPIO_CONFIG) && (addr < base::GPIO_CONFIG + GPIO_REG_SIZE*4)) {
00768 gpioRegs[(addr - base::GPIO_CONFIG)/4] = val;
00769 return 0;
00770 }
00771 }
00772
00773 printf("Roc:%u Put 0x%04x = 0x%04x Fails\n", gC.rocNumber, addr, val);
00774
00775 return 2;
00776 }
00777
00778 uint32_t UdpSimulator::NOper(int nodekind, uint32_t num, uint32_t* arr)
00779 {
00780 for (unsigned n=0; n<num; n++) {
00781 uint32_t addr_oper = ntohl(*arr); arr++;
00782 uint32_t value = ntohl(*arr);
00783
00784 uint32_t oper = addr_oper & NOPER_OPER_MASK;
00785 uint32_t addr = addr_oper & NOPER_ADDR_MASK;
00786
00787 if (oper == NOPER_PUT) {
00788 uint32_t res = PutReg(nodekind, addr, value, 0);
00789 if (res!=0) return res | (n << 8);
00790 } else
00791 if (oper == NOPER_GET) {
00792 uint32_t res = GetReg(nodekind, addr, &value);
00793 if (res!=0) return res | (n << 8);
00794 } else
00795 return 2 | (n << 8);
00796
00797 *arr = htonl(value); arr++;
00798 }
00799
00800 return 0;
00801 }
00802
00803
00804 void UdpSimulator::fillRareSyncData(uint8_t* target, uint16_t numOfDatas)
00805 {
00806 uint32_t nextepoch = 0;
00807
00808 uint64_t min = 0;
00809
00810 roc::Message msg;
00811
00812 while (numOfDatas > 0) {
00813
00814 min = nextTimeNoise;
00815 if (min > nextTimeSync) min = nextTimeSync;
00816 if (min > nextTimeAUX0) min = nextTimeAUX0;
00817 if (min > nextTimeAUX1) min = nextTimeAUX1;
00818 if (min > nextTimeHit) min = nextTimeHit;
00819
00820 bool accept_data = true;
00821
00822 nextepoch = min >> 14;
00823 msg.reset();
00824
00825 if (nextepoch != lastEpoch) {
00826 msg.setMessageType(roc::MSG_EPOCH);
00827 msg.setEpochNumber(nextepoch);
00828 lastEpoch = nextepoch;
00829 } else
00830
00831 if (nextTimeHit == min) {
00832
00833
00834
00835 msg.setMessageType(roc::MSG_HIT);
00836 msg.setNxNumber(rand() % 4);
00837 msg.setNxChNum(rand() % 128);
00838 msg.setNxTs(nextTimeHit & 0x3fff);
00839 msg.setNxAdcValue(rand() % 0x4000);
00840 msg.setNxLastEpoch(0);
00841
00842 nextHitCounter--;
00843 if (nextHitCounter == 0) {
00844 nextEventNumber++;
00845 nextHitCounter = 3 + (rand() % 6);
00846 nextTimeHit = uint64_t(nextEventNumber * 73747 * clockScrewUp);
00847 }
00848 nextTimeHit += (1 + rand() % 7);
00849 } else
00850
00851 if (nextTimeNoise == min) {
00852
00853
00854 msg.setMessageType(roc::MSG_HIT);
00855 msg.setNxNumber(rand() % 4);
00856 msg.setNxChNum(rand() % 128);
00857 msg.setNxTs(nextTimeNoise & 0x3fff);
00858 msg.setNxAdcValue(rand() % 0x4000);
00859 msg.setNxLastEpoch(0);
00860
00861 nextTimeNoise += (rand() % 0x4000);
00862 } else
00863
00864 if (nextTimeSync == min) {
00865
00866 accept_data = ((gpioConfig() >> (base::SYNC_S0*4)) & 3) != 0;
00867
00868 if (accept_data) {
00869 msg.setMessageType(roc::MSG_SYNC);
00870 msg.setSyncChNum(0);
00871 msg.setSyncTs(nextTimeSync & 0x3fff);
00872 msg.setSyncEpochLSB(nextepoch & 0x1);
00873 msg.setSyncData(nextSyncEvent & 0xffffffL);
00874 msg.setSyncStFlag(0);
00875 }
00876
00877
00878
00879 nextSyncEvent += (1 << syncMDelay());
00880 nextTimeSync = uint64_t(0x345 + nextSyncEvent * 0x4000 * clockScrewUp);
00881
00882 } else
00883
00884 if (nextTimeAUX0 == min) {
00885
00886 accept_data = (gpioConfig() & (1 << (base::AUX0*4 + (nextAUX0Falling ? 1 : 0)))) != 0;
00887
00888 if (accept_data) {
00889 msg.setMessageType(roc::MSG_AUX);
00890 msg.setAuxChNum(0);
00891 msg.setAuxTs(nextTimeAUX0 & 0x3fff);
00892 msg.setAuxEpochLSB(nextepoch & 0x1);
00893 msg.setAuxFalling(nextAUX0Falling ? 1 : 0);
00894 msg.setAuxOverflow(0);
00895 }
00896
00897 nextTimeAUX0 += periodAUX0;
00898 nextAUX0Falling = !nextAUX0Falling;
00899
00900 } else
00901
00902 if (nextTimeAUX1 == min) {
00903
00904 accept_data = (gpioConfig() & (1 << (base::AUX1*4 + (nextAUX1Falling ? 1 : 0)))) != 0;
00905
00906 if (accept_data) {
00907 msg.setMessageType(roc::MSG_AUX);
00908 msg.setAuxChNum(1);
00909 msg.setAuxTs(nextTimeAUX1 & 0x3fff);
00910 msg.setAuxEpochLSB(nextepoch & 0x1);
00911 msg.setAuxFalling(nextAUX1Falling ? 1 : 0);
00912 msg.setAuxOverflow(0);
00913 }
00914
00915 nextTimeAUX1 += periodAUX1;
00916 nextAUX1Falling = !nextAUX1Falling;
00917 }
00918
00919 if (accept_data) {
00920 msg.copyto(target, roc::formatEth2);
00921 numOfDatas--;
00922 target+=6;
00923 }
00924 }
00925 }
00926
00927 void UdpSimulator::makeSysMessage(uint8_t typ, uint32_t arg)
00928 {
00929 roc::Message msg;
00930
00931 msg.setMessageType(roc::MSG_SYS);
00932 msg.setSysMesType(typ);
00933 msg.setSysMesData(arg);
00934
00935 roc::UdpDataPacketFull pkt;
00936
00937
00938
00939
00940
00941
00942
00943
00944 msg.copyto(pkt.msgs, roc::formatEth2);
00945
00946 pkt.nummsg = htonl(1);
00947 pkt.pktid = htonl(gD.headid++);
00948 printf("Put sys msg %u arg %u in pkt with id %u\n", (unsigned) typ, (unsigned) arg, ntohl(pkt.pktid));
00949 gD.buf.push_back(pkt);
00950 }
00951
00952 void UdpSimulator::processDataRequest(roc::UdpDataRequestFull* pkt)
00953 {
00954 gD.last_req_pkt_id = pkt->reqpktid;
00955 gD.send_limit = pkt->frontpktid;
00956
00957
00958
00959 while (gD.buf.size() > 0) {
00960 uint32_t diff = pkt->tailpktid - ntohl(gD.buf.front().pktid);
00961 if ((diff !=0) && (diff < 0x1000000)) gD.buf.pop_front();
00962 else break;
00963 if ((gD.daqState==1) && !gD.data_taking_on)
00964 if (gD.buf.size() < gD.low_water)
00965 gD.data_taking_on = true;
00966 }
00967
00968 for (unsigned n=0; n<pkt->numresend; n++)
00969 if (gD.resend_size<RESEND_MAX_SIZE) {
00970 gD.resend_indx[gD.resend_size] = pkt->resend[n];
00971 gD.resend_size++;
00972 }
00973 }
00974
00975
00976 bool UdpSimulator::sendDataPacket(uint32_t pktid)
00977 {
00978 if (gD.droppkt_id == pktid) {
00979 printf("Explicit drop of packet 0x%x\n", gD.droppkt_id);
00980 gD.droppkt_id = rand();
00981 return true;
00982 }
00983
00984 if (gD.buf.size()==0) return false;
00985
00986
00987
00988
00989
00990
00991 std::list<roc::UdpDataPacketFull>::iterator iter = gD.buf.begin();
00992
00993 while (iter != gD.buf.end()) {
00994
00995 if (ntohl(iter->pktid) == pktid) {
00996 iter->lastreqid = htonl(gD.last_req_pkt_id);
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 if (!doSendLost()) {
01011 sendto(s_data,
01012 (char*) &(*iter),
01013 sizeof(roc::UdpDataPacket) + ntohl(iter->nummsg) * 6,
01014 MSG_DONTWAIT,
01015 (const sockaddr*) & gD.masterDataAddr,
01016 sizeof(gD.masterDataAddr));
01017
01018 sendDataSize += sizeof(roc::UdpDataPacket) + ntohl(iter->nummsg) * 6;
01019 }
01020
01021 return true;
01022 }
01023
01024 iter++;
01025 }
01026
01027 return false;
01028 }
01029
01030
01031
01032 void UdpSimulator::mainLoop()
01033 {
01034 roc::UdpDataPacketFull pkt;
01035
01036 printf("UdpSimulator is running...\n");
01037
01038 bool did_something = false;
01039 bool send_something = false;
01040
01041 gD.lastMasterTime = get_clock();
01042 double last_tm = get_clock();
01043 double last_stat_time = last_tm;
01044
01045 while (true) {
01046
01047 if (!did_something)
01048 dispatchNewSockets(100);
01049
01050 did_something = false;
01051
01052 if (gD.data_taking_on) {
01053 fillRareSyncData(pkt.msgs, 243);
01054 pkt.nummsg = htonl(243);
01055 pkt.pktid = htonl(gD.headid++);
01056 gD.buf.push_back(pkt);
01057 takeDataSize += 243*6;
01058
01059
01060 if (gD.buf.size() > gD.high_water) gD.data_taking_on = false;
01061 }
01062
01063
01064
01065 if (gD.cmdListPtr < ROC_CMD_LST_SIZE / 4) {
01066 if (gD.cmdsList[gD.cmdListPtr] & ROC_CMD_LST_PUT)
01067 PutReg(NODE_MASTER, gD.cmdsList[gD.cmdListPtr] & ROC_CMD_LST_ADDRMASK, gD.cmdsList[gD.cmdListPtr+1], 0);
01068 gD.cmdListPtr += 2;
01069 }
01070
01071 double curr_tm = get_clock();
01072
01073
01074 if (gD.daqState && (fabs(curr_tm - gD.lastFlushTime) > gC.flushTimeout*0.001)) {
01075
01076
01077 uint32_t prev_send_id = gD.next_send_id - 1;
01078
01079 if (!send_something)
01080 if (gD.headid - prev_send_id <= gD.buf.size())
01081 if (sendDataPacket(prev_send_id))
01082 printf("Flush buffer id 0x%x datataking %d total %u limit 0x%x next_send 0x%x \n", prev_send_id, gD.data_taking_on, (unsigned) gD.buf.size(), (unsigned) gD.send_limit, gD.next_send_id);
01083
01084 send_something = false;
01085 gD.lastFlushTime = get_clock();
01086 }
01087
01088 if (gD.masterConnected && fabs(curr_tm - gD.lastMasterTime) > 10) {
01089 printf("Disconnect master after 10 sec!\n");
01090 gD.masterConnected = false;
01091 gD.data_taking_on = false;
01092 gD.daqState = 0;
01093 }
01094
01095 if (gD.controlLocked && fabs(curr_tm - gD.lockedTime) > 3) {
01096 printf("Control unlocked after 3 sec!\n");
01097 gD.controlLocked = 0;
01098 }
01099
01100 if (gD.controlConnected && fabs(gD.lastControlTime - curr_tm) > 10) {
01101 printf("Disconnect control after 10 sec!\n");
01102 gD.controlConnected = false;
01103 }
01104
01105 if (fabs(gD.lastMasterTime - curr_tm) > 3000) {
01106 printf("No news from master last 3000 sec, stop main loop!!\n");
01107 break;
01108 }
01109
01110
01111 if (gD.resend_size > 0) {
01112 sendDataPacket(gD.resend_indx[--gD.resend_size]);
01113 did_something = true;
01114 send_something = true;
01115 } else
01116
01117 if (gD.send_limit != gD.next_send_id)
01118 if (gD.send_limit - gD.next_send_id < 0x1000000)
01119 if (sendDataPacket(gD.next_send_id)) {
01120 gD.next_send_id++;
01121 did_something = true;
01122 send_something = true;
01123 }
01124
01125 if (fabs(curr_tm - last_tm) > 10.) {
01126 if (totalSendLosts>0)
01127 printf("Send:%8u Lost:%5.1f%s\n", (unsigned) totalSendCounter, 100. * totalSendLosts/totalSendCounter, "%");
01128 if (totalRecvLosts>0)
01129 printf("Recv:%8u Lost:%5.1f%s\n", (unsigned) totalRecvCounter, 100. * totalRecvLosts/totalRecvCounter, "%");
01130 last_tm = curr_tm;
01131 }
01132
01133 if (curr_tm - last_stat_time >= 1.) {
01134 memset(&fStat, 0, sizeof(fStat));
01135 fStat.dataRate = takeDataSize;
01136 fStat.sendRate = sendDataSize;
01137 fStat.recvRate = recvDataSize;
01138
01139 takeDataSize = 0;
01140 recvDataSize = 0;
01141 sendDataSize = 0;
01142
01143 last_stat_time = curr_tm;
01144 }
01145 }
01146 }
01147