Example #1
0
void MessageProcessor::run()
{
    for (;;) {
        // timeout is the time left until the next cron should execute.
        int64_t timeout = server_->computeTimeout();
        if (timeout <= 0) {
            server_->ProcessCron();
            continue;
        }

        // wait for incoming message or up to timeout,
        // i.e. stop polling in time for the next cron execution.
        if (zpoller_wait(zmqPoller_, timeout)) {
            processSocket();
            continue;
        }
        if (zpoller_terminated(zmqPoller_)) {
            otErr << __FUNCTION__
                  << ": zpoller_terminated - process interrupted or"
                  << " parent context destroyed\n";
            break;
        }

        if (!zpoller_expired(zmqPoller_)) {
            otErr << __FUNCTION__ << ": zpoller_wait error\n";
            // we do not want busy loop if something goes wrong
            Log::SleepMilliseconds(100);
        }
    }
}
Example #2
0
void Server::run() {
	if (m_wordList.size() == 0)
		return;

	cpp3ds::Clock pingClock;

	if (m_listener.listen(m_port) == cpp3ds::Socket::Done) {
		m_selector.add(m_listener);
		std::cout << "Started DrawAttack server on port " << m_port << "..." << std::endl;
		m_running = true;
		while (m_running) {
			// Make the selector wait for data on any socket
			if (m_selector.wait(cpp3ds::milliseconds(1000))) {
				if (m_selector.isReady(m_listener)) {
					cpp3ds::TcpSocket* socket = new cpp3ds::TcpSocket;
					if (m_listener.accept(*socket) == cpp3ds::Socket::Done)
					{
						std::cout << "client connected" << std::endl;
						// Add the new client to the clients list
						sendPlayerData(socket);
						socket->send(m_drawDataPacket);
						m_pingResponses[socket] = true;
						m_sockets.emplace_back(socket);
						m_selector.add(*socket);
					} else {
						delete socket;
					}
				}
				else
				{
					for (auto& socket : m_sockets) {
						if (m_selector.isReady(*socket)) {
							processSocket(socket);
						}
					}
				}
			}

			// Ping clients and check for previous response
			if (pingClock.getElapsedTime() >= cpp3ds::seconds(PING_TIMEOUT)) {
				cpp3ds::Packet packet;
				packet << NetworkEvent::Ping;
				for (auto i = m_sockets.begin(); i != m_sockets.end();) {
					if (m_pingResponses[*i]) {
						(*i)->send(packet);
						m_pingResponses[*i] = false;
						i++;
					} else {
						// Timed out socket
						std::cout << "A socket timed out." << std::endl;
						removeSocket(*i);
					}
				}
				pingClock.restart();
			}

			if (m_mode == Play) {
				if (m_roundClock.getElapsedTime() >= cpp3ds::seconds(ROUND_DURATION)) {
					// Round time ended, nobody won
					cpp3ds::Packet packet;
					packet << NetworkEvent::RoundWord << m_currentWord << NetworkEvent::RoundFail;
					sendToAllSockets(packet);
					m_roundClock.restart();
					m_mode = Wait;
				}
				if (m_roundTimeoutClock.getElapsedTime() >= cpp3ds::seconds(ROUND_TIMEOUT)) {
					// Drawer hasn't been active, so end round
					cpp3ds::Packet packet;
					packet << NetworkEvent::RoundWord << m_currentWord << NetworkEvent::RoundTimeout;
					sendToAllSockets(packet);
					m_roundClock.restart();
					m_mode = Wait;
				}
			} else if (m_mode == Wait) {
				if (m_players.size() >= MIN_PLAYERS) {
					if (m_roundClock.getElapsedTime() >= cpp3ds::seconds(ROUND_INTERMISSION)) {
						Player drawer = getNextDrawer();
						startRound(drawer, getNextWord(), ROUND_DURATION);
					}
				}
			}
		}
	} else {
		cpp3ds::err() << "Failed to listen on port " << m_port << std::endl;
	}
}
Example #3
0
int main(int argc, char *argv[])
// arg1: controller number
{
	int nolog = 0;

    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
	int run = 1;		// set to 0 to stop main loop
	fd_set readfd; 
	int numfds;
	int interval = 60;
	int tmout = 90;	// seconds to wait in select()
	int saveInterval = 600;	// Save to NVRAM every 10 mins
	int logerror = 0;
	int option; 
	int delay = 1000;		// usec to sleep (but it rounds up to 20mSec anyway
	time_t update = 0, now;
	pthread_t tid;
	time_t nextSave;

	// Command line arguments
	
	opterr = 0;
	while ((option = getopt(argc, argv, "di:slVZ1:2:")) != -1) {
		switch (option) {
			case 's': noserver = 1; break;
			case 'l': nolog = 1; break;
			case '?': usage(); exit(1);
			case 'i': interval = atoi(optarg); break;
			case 'd': debug++; break;
			case '1': rate1 = rate2 = atof(optarg);	break;
			case '2': rate2 = atof(optarg);	break;
			case 'V': printf("Version %s %s\n", getversion(), id); exit(0);
			case 'Z': decode("(b+#Gjv~z`mcx-@ndd`rxbwcl9Vox=,/\x10\x17\x0e\x11\x14\x15\x11\x0b\x1a" 
							 "\x19\x1a\x13\x0cx@NEEZ\\F\\ER\\\x19YTLDWQ'a-1d()#!/#(-9' >q\"!;=?51-??r"); exit(0);
		}
	}
	
	DEBUG printf("Debug %d. optind %d argc %d\n", debug, optind, argc);
	
	if (optind < argc) controllernum = atoi(argv[optind]);	// get optional controller number: parameter 1
	
	sprintf(buffer, LOGFILE, controllernum);
	
	if (!nolog) if ((logfp = fopen(buffer, "a")) == NULL) logerror = errno;	
	
	// There is no point in logging the failure to open the logfile
	// to the logfile, and the socket is not yet open.

	sprintf(buffer, "STARTED %s as %d interval %d %s", argv[0], controllernum, interval, nolog ? "nolog" : "");
	logmsg(INFO, buffer);
	
	// Set up socket 
	if (!noserver) {
		sockfd = socket(AF_INET, SOCK_STREAM, 0);
		if (sockfd < 0) 
			logmsg(FATAL, "FATAL " PROGNAME " Creating socket");
		server = gethostbyname("localhost");
		if (server == NULL) {
			logmsg(FATAL, "FATAL " PROGNAME " Cannot resolve localhost");
		}
		bzero((char *) &serv_addr, sizeof(serv_addr));
		serv_addr.sin_family = AF_INET;
		bcopy((char *)server->h_addr, 
			 (char *)&serv_addr.sin_addr.s_addr,
			 server->h_length);
		serv_addr.sin_port = htons(PORTNO);
		if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
			sockfd = 0;
			logmsg(ERROR, "ERROR " PROGNAME " Connecting to socket");
		}	
		
		if (flock(fileno(logfp), LOCK_EX | LOCK_NB) == -1) {
			logmsg(FATAL, "FATAL " PROGNAME " is already running, cannot start another one");
		}
	
		// Logon to server as meter
		sprintf(buffer, "logon " progname " %s %d %d", getversion(), getpid(), controllernum);
		sockSend(buffer);
	}
	else	sockfd = 1;		// noserver: use stdout
	
	// If we failed to open the logfile and were NOT called with nolog, warn server
	// Obviously don't use logmsg!
	if (logfp == NULL && nolog == 0) {
		sprintf(buffer, "event WARN " PROGNAME " %d could not open logfile %s: %s", controllernum, LOGFILE, strerror(logerror));
		sockSend(buffer);
	}
		
	// Set up hardware
	
	int mem = open("/dev/mem", O_RDWR);
	unsigned char * start = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, mem, 0x80840000);
	pbdata = (unsigned int*)(start + 0x04);
	pbddr = (unsigned int *)(start + 0x14);
	// All inputs
	*pbddr = DIO4 | DIO5;  // DIO 4/5 outputs.
	*pbdata = 0xff;		// set to all 1's

	numfds = sockfd + 1;		// nfds parameter to select. One more than highest descriptor

	// Main Loop
	count1 = count2 = 0;
	readCMOS();
	DEBUG fprintf(stderr, "Got values from NVRAM: %d %d (%f %f)\n",  
				  count1, count2, (count1 / rate1), (count2 / rate2));

	// Start count thread
	if (pthread_create(&tid, NULL, count_pulses, NULL) < 0)
		perror("count_pulse");
	DEBUG fprintf(stderr, "Thread started as %d (0x%x)\n", tid, tid);

	FD_ZERO(&readfd); 

	update = timeMod(interval);
	nextSave = timeMod(saveInterval);
	while(run) {
		struct timeval tv1;
		now = time(NULL);
		if (now > nextSave) {
			DEBUG fprintf(stderr, "Saving to NVRAM ");
			writeCMOS();
			nextSave = timeMod(saveInterval);
			DEBUG {
				struct tm * t;
				t = localtime(&nextSave);
				strftime(buffer, sizeof(buffer), "%F %T", t);
				fprintf(stderr, "Next save at %s\n", buffer);
			}
		}

		if (now > update) {	// message time.  Will always send out 0 0 at startup.
			int fd;
			sprintf(buffer, "meter 2 %.1f %.1f", (count1 / rate1), (count2 / rate2));
			sockSend(buffer);
			update = timeMod(interval);
			// Write to /tmp/pulse
			fd = open("/tmp/pulse", O_RDWR | O_CREAT | O_TRUNC);
			if (fd < 0) perror("/tmp/pulse");
			if (fd > 0) {
				strcat(buffer, "\n");
				write(fd, buffer, strlen(buffer));
				close(fd);
			}
		}
		
		FD_SET(sockfd, &readfd);
		tv1.tv_sec = 0;
		tv1.tv_usec = tmout;
		if (select(sockfd + 1, &readfd, NULL, NULL, &tv1) && sockfd > 1)	// anything from server?
			run = processSocket();	// the server may request a shutdown by setting run to 0
		usleep(delay);
	}
Example #4
0
int main(int argc, char **argv)
{
	in_port_t port = DEFAULT_PORT;
	long baud = DEFAULT_BAUD;
	char dv3000tty[MAXPATHLEN] = DEFAULT_TTY;
	
	fd_set fds;
	int serialFd;
	int sockFd;
	int topFd;
	
	int c;

#ifdef __CYGWIN__
	int commnum;
#endif
	
	char reset = 0;
	char daemon = 0;

	setvbuf(stdout, NULL, _IOLBF, 0);
	setvbuf(stderr, NULL, _IOLBF, 0);

#ifdef __CYGWIN__
	while ((c = getopt(argc, argv, "dp:s:c:vxrh")) != -1) {
#else
	while ((c = getopt(argc, argv, "dp:s:i:vxrh")) != -1) {
#endif
		switch (c) {
			case 'd':
				daemon = 1;
				break;
			case 'p':
				errno = 0;
				port = strtol(optarg, NULL, 10);
				if(errno != 0 || port == 0) {
					fprintf(stderr, "Invalid port number: %s\n", optarg);
					usage();
				}
				break;
			case 's':
				errno = 0;
				baud = strtol(optarg, NULL, 10);
				if(errno != 0 || baud == 0) {
					fprintf(stderr, "Invalid baud rate: %s\n", optarg);
					usage();
				}
				break;
#ifdef __CYGWIN__
			case 'c':
				commnum = strtol(optarg, NULL, 10);
				sprintf(dv3000tty,"/dev/ttyS%d",commnum - 1);
				break;
#else
			case 'i':
				strncpy(dv3000tty, optarg, sizeof(dv3000tty));
				break;
#endif
			case 'v':
				fprintf(stdout, "AMBEserver: version " DV3000_VERSION "\n");
				return 0;
			case 'x':
				debug = 1;
				break;
			case 'r':
				reset = 1;
				break;
			case 'h':
			default:
				usage();
				break;
		}
	}
	
	if (strlen(dv3000tty) < 1) {
		fprintf(stderr, "An input tty filename (-i /dev/ttyXXX) must be set.\n");
		return 1;
	}

	if (daemon) {
		pid_t pid = fork();

		if (pid < 0) {
			fprintf(stderr, "AMBEserver: error in fork(), exiting\n");
			exit(1);
		}

		// If this is the parent, exit
		if (pid > 0)
			exit(0);

		// We are the child from here onwards
		setsid();

		umask(0);
	}

	fprintf(stdout, "AMBEserver: Starting...\n");

	serialFd = openSerial(dv3000tty, baud);
	if (serialFd < 0)
		exit(1);

	fprintf(stdout, "AMBEserver: Opened serial port %s at %ld bps.\n", dv3000tty, baud);
	
	if(initDV3K(serialFd, reset) == 0) {
		fprintf(stderr, "AMBEserver: Could not initialize the DV3K!\n");
		exit(1);
	}
	
	sockFd = openSocket(port);
	if (sockFd < 0)
		exit(1);

	fprintf(stdout, "AMBEserver: Listening for connections on UDP port %d.\n", port);
		
	topFd = (sockFd > serialFd ? sockFd : serialFd ) + 1;

	for (;;) {
		FD_ZERO(&fds);
		FD_SET(sockFd, &fds);
		FD_SET(serialFd, &fds);

		if (select(topFd, &fds, NULL, NULL, NULL) < 0) {
			fprintf(stderr, "AMBEserver: error from select: %s\n", strerror(errno));
			exit(1);
		}
		
		if(FD_ISSET(sockFd, &fds))
			if (!processSocket(sockFd, serialFd))
				exit(1);

		if(FD_ISSET(serialFd, &fds))
			if (!processSerial(sockFd, serialFd))
				exit(1);
	}

	exit(0);
}