static int handle_client(int client_fd) { int status; size_t size, nitems; FILE *serial_file; char buf[1024]; /* buffer for serial IO */ CapCommand cmd; char ruser[64], rhost[64], realhost[64]; double rate, time; fd_set rd_fds; struct timeval timeout, now, *timeoutPtr; int recording = 0; double recordNow = 0.; double recordNext = 0.; double recordPeriod = 0.; double recordDelta = 0.; #ifdef _WIN32 int ms; #endif while (1) { FD_ZERO(&rd_fds); FD_SET(client_fd, &rd_fds); if ( !recording ) { timeoutPtr = NULL; } else { /* record and schedule the next recording */ #ifdef LINUX gettimeofday(&now, NULL); #else gettimeofday(&now); #endif recordNow = toDouble(now); if ( recordNext == 0.0 ) /* The first record */ recordNext = recordNow; while ( recordNext <= recordNow ) { get_data(client_fd); recordNext = recordNext + recordPeriod; } timeout = toTimeval( recordNext - recordNow ); timeoutPtr = &timeout; } /* * wait for commands or a timeout */ #ifndef _WIN32 status = select(FD_SETSIZE, &rd_fds, NULL, NULL, timeoutPtr); #else /* Should really use CapWaitTimeout when possible */ ms = -1; if (timeoutPtr) ms = timeoutPtr->tv_sec*1000 + timeoutPtr->tv_usec/1000; status = CapWaitTimeout(client_fd, ms); #endif if (status < 0 ) { if (errno == EINTR) { /* Ignore signals and try again */ continue; } /* Otherwise, give a fatal error message */ CapError(client_fd, CAP_SEV_FATAL, gProgramName, "select failed"); CapError(client_fd, CAP_SEV_FATAL, "select", NULL); exit(1); } else if (status == 0) { /* Try again */ continue; } /* There is data on the client file descriptor */ cmd = CapGetCommand(client_fd); switch (cmd) { case CAP_CMD_QUIT: return 0; case CAP_CMD_AUTHORIZE: status = CapGetAuthInfo(client_fd, ruser, rhost, realhost); if (status < 0) { return -1; } /* * If user@host is not authorized to use this server then: * * status = CapAuthorize(client_fd, 0); */ status = CapAuthorize(client_fd, 1); break; case CAP_CMD_INIT: /* Initial client/server handshake */ status = CapInitialize(client_fd, gProgramName); break; case CAP_CMD_VERSION: /* Send version information */ status = CapVersion(client_fd, gProgramName, "1.0", "Extern server (example) - v1.0"); break; case CAP_CMD_INFO: if (NULL == gChannels) { /* Only create the channel data once */ gChannels = create_channels(gConfigFile, client_fd); if ( NULL == gChannels) { status = CapError(client_fd, CAP_SEV_ERROR, gProgramName, "Missing or empty config file"); } } /* Return the recording information. gMaxRecordRate <= 0. * says recording is not supported */ { size_t buf_size = 0; if ( 0. < gMaxRecordRate) buf_size = INT_MAX; status = CapInfo(client_fd, gMinRecordRate, gMaxRecordRate, gDefRecordRate, buf_size, 1); } break; case CAP_CMD_DATA: /* Send frame data */ if (!recording ) get_data(client_fd); status = CapData(client_fd); break; case CAP_CMD_START_RECORD: /* Start recording */ rate = CapGetRequestedRecordRate(client_fd); size = CapGetRequestedRecordSize(client_fd); /* * Set up for recording operations */ if (rate < gMinRecordRate ) rate = gMinRecordRate; else if (rate > gMaxRecordRate ) rate = gMaxRecordRate; status = CapStartRecord(client_fd, rate, size); if (status != -1) { recordPeriod = 1.0 / rate; recordNext = 0.; recording = 1; } break; case CAP_CMD_STOP_RECORD: /* Stop recording */ status = CapStopRecord(client_fd); recording = 0; break; default: /* Ignore unknown commands */ status = CapError(client_fd, CAP_SEV_ERROR, gProgramName, "Unknown server command."); break; } if (status < 0) { return -1; } } /* return 0; */ }
static int handle_client(int client_fd) { int status; CapCommand cmd; char ruser[64], rhost[64], realhost[64]; fd_set rd_fds; struct timeval base_timeout, timeout; int recording = 0; static int channels_created = 0; base_timeout.tv_sec = 1; base_timeout.tv_usec = 0; while (1) { FD_ZERO(&rd_fds); FD_SET((unsigned int)client_fd, &rd_fds); timeout.tv_sec = base_timeout.tv_sec; timeout.tv_usec = base_timeout.tv_usec; status = select(FD_SETSIZE, &rd_fds, NULL, NULL, &timeout); if (status < 0) { #ifndef _WIN32 if (errno == EINTR) { /* Ignore signals and try again */ continue; } #endif /*WIN32*/ /* Otherwise, give a fatal error message */ CapError(client_fd, CAP_SEV_FATAL, program, "select failed"); CapError(client_fd, CAP_SEV_FATAL, "select", NULL); exit(1); } else if (status == 0) { /* We got a timeout */ if (recording) get_data(client_fd); /* Try again */ continue; } else { /* There is data on the client file descriptor */ cmd = CapGetCommand(client_fd); switch (cmd) { case CAP_CMD_QUIT: return 0; #ifdef _WIN32 case CAP_CMD_ERROR: return -1; #endif case CAP_CMD_AUTHORIZE: status = CapGetAuthInfo(client_fd, ruser, rhost, realhost); if (status < 0) { return -1; } /* * If user@host is not authorized to use this server then: * * status = CapAuthorize(client_fd, 0); */ status = CapAuthorize(client_fd, 1); break; case CAP_CMD_INIT: /* Initial client/server handshake */ status = CapInitialize(client_fd, program); break; case CAP_CMD_VERSION: /* Send version information */ status = CapVersion(client_fd, program, "1.0", "Clock capture server - v1.0"); break; case CAP_CMD_INFO: if (!channels_created) { /* Only create the channel data once */ status = create_channels(client_fd); if (status < 0) { break; } channels_created = 1; } #ifdef SERVER_SIDE_RECORDING /* The server side recording returns incorrect time in * the current version */ status = CapInfo(client_fd, 1.0, 100.0, 10.0, 512 * 1024, 1); #else status = CapInfo(client_fd, 0.0, 0.0, 0.0, 512 * 1024, 1); #endif break; case CAP_CMD_DATA: /* Send frame data */ get_data(client_fd); status = CapData(client_fd); break; #ifdef SERVER_SIDE_RECORDING /* The server side recording returns incorrect time in * the current version */ case CAP_CMD_START_RECORD: /* Start recording */ { int size = 0; float rate = 0.0f, time = 0.0f; rate = CapGetRequestedRecordRate(client_fd); size = CapGetRequestedRecordSize(client_fd); /* Convert rate in Hz to a timeout value in a timeval structure */ if (rate < 1.0) rate = 1.0; if (rate > 100.0) rate = 100.0; time = 1.0 / rate; base_timeout.tv_sec = time; base_timeout.tv_usec = (time - base_timeout.tv_sec) * 1000000; status = CapStartRecord(client_fd, rate, size); if (status != -1) { recording = 1; } break; } case CAP_CMD_STOP_RECORD: /* Stop recording */ status = CapStopRecord(client_fd); recording = 0; base_timeout.tv_sec = 1; base_timeout.tv_usec = 0; break; #endif /* server side recording */ default: /* Ignore unknown commands */ status = CapError(client_fd, CAP_SEV_ERROR, program, "Unknown server command."); break; } if (status < 0) { return -1; } } } /* return 0; */ }