ssize_t timedRead(int fd, void *buf, size_t count, int initialtimeout, int interbytetimeout) { fd_set rset; struct timeval timeout; int result; size_t totalread = 0; while (totalread < count) { FD_ZERO(&rset); FD_SET(fd, &rset); if (totalread == 0) { timeout.tv_sec = initialtimeout/1000; timeout.tv_usec = (initialtimeout%1000) * 1000; } else { timeout.tv_sec = interbytetimeout / 1000; timeout.tv_usec = (interbytetimeout%1000) * 1000; } if ((result = select(fd + 1, &rset, NULL, NULL, &timeout)) < 0) return -1; /* error */ if (result == 0) break; if ((result = singleRead(fd, ((char*)buf) + totalread, count - totalread)) < 0) { return -1; } if (result == 0) break; totalread += result; } return totalread; }
//Read RPM average from 100 reads int ShootRotorEncoder::ReadRPM(){ int readTable[100]; for(int i = 0; i <= 99; i++){ readTable[i] = singleRead(); } int readSum = std::accumulate(std::begin(readTable), std::end(readTable), 0, std::plus<int>()); int avg = (readSum / 100); return avg; }
bool DatabaseImpl::fetch(const boost::string_ref& key, partNum_t partNum, std::string& value) { checkSimpleArgumentFor(key, partNum); SingleRead singleRead(key, partNum, value); return doFetch(singleRead); }
void eStreamClient::notifier(int what) { if (!(what & eSocketNotifier::Read)) return; ePtr<eStreamClient> ref = this; char buf[512]; int len; if ((len = singleRead(streamFd, buf, sizeof(buf))) <= 0) { rsn->stop(); stop(); parent->connectionLost(this); return; } request.append(buf, len); if (running || (request.find('\n') == std::string::npos)) return; if (request.substr(0, 5) == "GET /") { size_t pos; if (eConfigManager::getConfigBoolValue("config.streaming.authentication")) { bool authenticated = false; if ((pos = request.find("Authorization: Basic ")) != std::string::npos) { std::string authentication, username, password; std::string hash = request.substr(pos + 21); pos = hash.find('\r'); hash = hash.substr(0, pos); hash += "\n"; { char *in, *out; in = strdup(hash.c_str()); out = (char*)calloc(1, hash.size()); if (in && out) { BIO *b64, *bmem; b64 = BIO_new(BIO_f_base64()); bmem = BIO_new_mem_buf(in, hash.size()); bmem = BIO_push(b64, bmem); BIO_read(bmem, out, hash.size()); BIO_free_all(bmem); authentication.append(out, hash.size()); } free(in); free(out); } pos = authentication.find(':'); if (pos != std::string::npos) { char *buffer = (char*)malloc(4096); if (buffer) { struct passwd pwd; struct passwd *pwdresult = NULL; std::string crypt; username = authentication.substr(0, pos); password = authentication.substr(pos + 1); getpwnam_r(username.c_str(), &pwd, buffer, 4096, &pwdresult); if (pwdresult) { struct crypt_data cryptdata; char *cryptresult = NULL; cryptdata.initialized = 0; crypt = pwd.pw_passwd; if (crypt == "*" || crypt == "x") { struct spwd spwd; struct spwd *spwdresult = NULL; getspnam_r(username.c_str(), &spwd, buffer, 4096, &spwdresult); if (spwdresult) { crypt = spwd.sp_pwdp; } } cryptresult = crypt_r(password.c_str(), crypt.c_str(), &cryptdata); authenticated = cryptresult && cryptresult == crypt; } free(buffer); } } } if (!authenticated) { const char *reply = "HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"streamserver\"\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } } pos = request.find(' ', 5); if (pos != std::string::npos) { std::string serviceref = urlDecode(request.substr(5, pos - 5)); if (!serviceref.empty()) { const char *reply = "HTTP/1.0 200 OK\r\nConnection: Close\r\nContent-Type: video/mpeg\r\nServer: streamserver\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); if (serviceref.substr(0, 10) == "file?file=") /* convert openwebif stream reqeust back to serviceref */ serviceref = "1:0:1:0:0:0:0:0:0:0:" + serviceref.substr(10); pos = serviceref.find('?'); if (pos == std::string::npos) { if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) running = true; } else { request = serviceref.substr(pos); serviceref = serviceref.substr(0, pos); pos = request.find("?bitrate="); if (pos != std::string::npos) { /* we need to stream transcoded data */ int bitrate = 1024 * 1024; int width = 720; int height = 576; int framerate = 25000; int interlaced = 0; int aspectratio = 0; sscanf(request.substr(pos).c_str(), "?bitrate=%d", &bitrate); pos = request.find("?width="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?width=%d", &width); pos = request.find("?height="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?height=%d", &height); pos = request.find("?framerate="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?framerate=%d", &framerate); pos = request.find("?interlaced="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?interlaced=%d", &interlaced); pos = request.find("?aspectratio="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?aspectratio=%d", &aspectratio); encoderFd = parent->allocateEncoder(this, serviceref, bitrate, width, height, framerate, !!interlaced, aspectratio); if (encoderFd >= 0) { running = true; streamThread = new eDVBRecordStreamThread(188); if (streamThread) { streamThread->setTargetFD(streamFd); streamThread->start(encoderFd); } } } } } } } if (!running) { const char *reply = "HTTP/1.0 400 Bad Request\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } request.clear(); }
void eStreamClient::notifier(int what) { if (what & eSocketNotifier::Read) { char buf[512]; int len; if ((len = singleRead(streamFd, buf, sizeof(buf))) <= 0) { rsn->stop(); stop(); parent->connectionLost(this); return; } request.append(buf, len); if (!running) { if (request.find('\n') != std::string::npos) { if (request.substr(0, 5) == "GET /") { size_t pos; if (eConfigManager::getConfigBoolValue("config.streaming.authentication")) { bool authenticated = false; if ((pos = request.find("Authorization: Basic ")) != std::string::npos) { std::string authentication, username, password; std::string hash = request.substr(pos + 21); pos = hash.find('\r'); hash = hash.substr(0, pos); hash += "\n"; { char *in, *out; in = strdup(hash.c_str()); out = (char*)calloc(1, hash.size()); if (in && out) { BIO *b64, *bmem; b64 = BIO_new(BIO_f_base64()); bmem = BIO_new_mem_buf(in, hash.size()); bmem = BIO_push(b64, bmem); BIO_read(bmem, out, hash.size()); BIO_free_all(bmem); authentication.append(out, hash.size()); } free(in); free(out); } pos = authentication.find(':'); if (pos != std::string::npos) { char *buffer = (char*)malloc(4096); if (buffer) { struct passwd pwd; struct passwd *pwdresult = NULL; std::string crypt; username = authentication.substr(0, pos); password = authentication.substr(pos + 1); getpwnam_r(username.c_str(), &pwd, buffer, 4096, &pwdresult); if (pwdresult) { struct crypt_data cryptdata; char *cryptresult = NULL; cryptdata.initialized = 0; crypt = pwd.pw_passwd; if (crypt == "*" || crypt == "x") { struct spwd spwd; struct spwd *spwdresult = NULL; getspnam_r(username.c_str(), &spwd, buffer, 4096, &spwdresult); if (spwdresult) { crypt = spwd.sp_pwdp; } } cryptresult = crypt_r(password.c_str(), crypt.c_str(), &cryptdata); authenticated = cryptresult && cryptresult == crypt; } free(buffer); } } } if (!authenticated) { const char *reply = "HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"streamserver\"\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } } pos = request.find(' ', 5); if (pos != std::string::npos) { std::string serviceref = urlDecode(request.substr(5, pos - 5)); if (!serviceref.empty()) { const char *reply = "HTTP/1.0 200 OK\r\nConnection: Close\r\nContent-Type: video/mpeg\r\nServer: streamserver\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) { running = true; } } } } if (!running) { const char *reply = "HTTP/1.0 400 Bad Request\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } request.clear(); } } } }
void eStreamClient::notifier(int what) { if (!(what & eSocketNotifier::Read)) return; ePtr<eStreamClient> ref = this; char buf[512]; int len; if ((len = singleRead(streamFd, buf, sizeof(buf))) <= 0) { rsn->stop(); stop(); parent->connectionLost(this); return; } request.append(buf, len); if (running || (request.find('\n') == std::string::npos)) return; if (request.substr(0, 5) == "GET /") { size_t pos; size_t posdur; if (eConfigManager::getConfigBoolValue("config.streaming.authentication")) { bool authenticated = false; if ((pos = request.find("Authorization: Basic ")) != std::string::npos) { std::string authentication, username, password; std::string hash = request.substr(pos + 21); pos = hash.find('\r'); hash = hash.substr(0, pos); authentication = base64decode(hash); pos = authentication.find(':'); if (pos != std::string::npos) { char *buffer = (char*)malloc(4096); if (buffer) { struct passwd pwd; struct passwd *pwdresult = NULL; std::string crypt; username = authentication.substr(0, pos); password = authentication.substr(pos + 1); getpwnam_r(username.c_str(), &pwd, buffer, 4096, &pwdresult); if (pwdresult) { struct crypt_data cryptdata; char *cryptresult = NULL; cryptdata.initialized = 0; crypt = pwd.pw_passwd; if (crypt == "*" || crypt == "x") { struct spwd spwd; struct spwd *spwdresult = NULL; getspnam_r(username.c_str(), &spwd, buffer, 4096, &spwdresult); if (spwdresult) { crypt = spwd.sp_pwdp; } } cryptresult = crypt_r(password.c_str(), crypt.c_str(), &cryptdata); authenticated = cryptresult && cryptresult == crypt; } free(buffer); } } } if (!authenticated) { const char *reply = "HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"streamserver\"\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } } pos = request.find(' ', 5); if (pos != std::string::npos) { std::string serviceref = urlDecode(request.substr(5, pos - 5)); if (!serviceref.empty()) { const char *reply = "HTTP/1.0 200 OK\r\nConnection: Close\r\nContent-Type: video/mpeg\r\nServer: streamserver\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); /* We don't expect any incoming data, so set a tiny buffer */ set_socket_option(streamFd, SO_RCVBUF, 1 * 1024); /* We like 188k packets, so set the TCP window size to that */ set_socket_option(streamFd, SO_SNDBUF, 188 * 1024); /* activate keepalive */ set_socket_option(streamFd, SO_KEEPALIVE, 1); /* configure keepalive */ set_tcp_option(streamFd, TCP_KEEPINTVL, 10); // every 10 seconds set_tcp_option(streamFd, TCP_KEEPIDLE, 1); // after 1 second of idle set_tcp_option(streamFd, TCP_KEEPCNT, 2); // drop connection after second miss /* also set 10 seconds data push timeout */ set_tcp_option(streamFd, TCP_USER_TIMEOUT, 10 * 1000); if (serviceref.substr(0, 10) == "file?file=") /* convert openwebif stream reqeust back to serviceref */ serviceref = "1:0:1:0:0:0:0:0:0:0:" + serviceref.substr(10); /* Strip session ID from URL if it exists, PLi streaming can not handle it */ pos = serviceref.find("&sessionid="); if (pos != std::string::npos) { serviceref.erase(pos, std::string::npos); } pos = serviceref.find("?sessionid="); if (pos != std::string::npos) { serviceref.erase(pos, std::string::npos); } pos = serviceref.find('?'); if (pos == std::string::npos) { eDebug("[eDVBServiceStream] stream ref: %s", serviceref.c_str()); if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) { running = true; m_serviceref = serviceref; m_useencoder = false; } } else { request = serviceref.substr(pos); serviceref = serviceref.substr(0, pos); pos = request.find("?bitrate="); posdur = request.find("?duration="); eDebug("[eDVBServiceStream] stream ref: %s", serviceref.c_str()); if (posdur != std::string::npos) { if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) { running = true; m_serviceref = serviceref; m_useencoder = false; } int timeout = 0; sscanf(request.substr(posdur).c_str(), "?duration=%d", &timeout); eDebug("[eDVBServiceStream] duration: %d seconds", timeout); if (timeout) { m_timeout->startLongTimer(timeout); } } else if (pos != std::string::npos) { /* we need to stream transcoded data */ int bitrate = 1024 * 1024; int width = 720; int height = 576; int framerate = 25000; int interlaced = 0; int aspectratio = 0; sscanf(request.substr(pos).c_str(), "?bitrate=%d", &bitrate); pos = request.find("?width="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?width=%d", &width); pos = request.find("?height="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?height=%d", &height); pos = request.find("?framerate="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?framerate=%d", &framerate); pos = request.find("?interlaced="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?interlaced=%d", &interlaced); pos = request.find("?aspectratio="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?aspectratio=%d", &aspectratio); encoderFd = -1; if (eEncoder::getInstance()) encoderFd = eEncoder::getInstance()->allocateEncoder(serviceref, bitrate, width, height, framerate, !!interlaced, aspectratio); if (encoderFd >= 0) { running = true; streamThread = new eDVBRecordStreamThread(188); if (streamThread) { streamThread->setTargetFD(streamFd); streamThread->start(encoderFd); } m_serviceref = serviceref; m_useencoder = true; } } } } } } if (!running) { const char *reply = "HTTP/1.0 400 Bad Request\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } request.clear(); }