void MyThread::run(){ LogReader logreader; LogSender logsender; list<MatchedLogRec> matches= logreader.readLogs(); /*准备发送数据*/ logsender.initNetWork(); char datastr[100]={0}; /*循环发送数据*/ while(matches.size()>0){ sleep(1); bool f=logsender.sendMatche(*matches.begin()); if(f){ /*发射信号*/ sprintf(datastr,"%s:%d:%s",matches.begin()->logname, matches.begin()->pid,matches.begin()->logip); emit mySig(QString(datastr)); /*删除这条数据*/ matches.erase(matches.begin()); }else{ break; } } /*关闭fd*/ logsender.saveSendFailed(&matches); }
int main(){ LogReader logreader; LogSender logsender; list<MatchedLogRec> matches= logreader.readLogs(); logsender.sendMatches(&matches); }
void Replay::setup() { ::printf("Starting\n"); uint8_t argc; char * const *argv; hal.util->commandline_arguments(argc, argv); _parse_command_line(argc, argv); if (!check_generate) { logreader.set_save_chek_messages(true); } // _parse_command_line sets up an FPE handler. We can do better: signal(SIGFPE, _replay_sig_fpe); hal.console->printf("Processing log %s\n", filename); // remember filename for reporting log_filename = filename; if (!find_log_info(log_info)) { printf("Update to get log information\n"); exit(1); } hal.console->printf("Using an update rate of %u Hz\n", log_info.update_rate); if (!logreader.open_log(filename)) { perror(filename); exit(1); } _vehicle.setup(); inhibit_gyro_cal(); set_ins_update_rate(log_info.update_rate); feenableexcept(FE_INVALID | FE_OVERFLOW); plotf = fopen("plot.dat", "w"); plotf2 = fopen("plot2.dat", "w"); ekf1f = fopen("EKF1.dat", "w"); ekf2f = fopen("EKF2.dat", "w"); ekf3f = fopen("EKF3.dat", "w"); ekf4f = fopen("EKF4.dat", "w"); fprintf(plotf, "time SIM.Roll SIM.Pitch SIM.Yaw BAR.Alt FLIGHT.Roll FLIGHT.Pitch FLIGHT.Yaw FLIGHT.dN FLIGHT.dE FLIGHT.Alt AHR2.Roll AHR2.Pitch AHR2.Yaw DCM.Roll DCM.Pitch DCM.Yaw EKF.Roll EKF.Pitch EKF.Yaw INAV.dN INAV.dE INAV.Alt EKF.dN EKF.dE EKF.Alt\n"); fprintf(plotf2, "time E1 E2 E3 VN VE VD PN PE PD GX GY GZ WN WE MN ME MD MX MY MZ E1ref E2ref E3ref\n"); fprintf(ekf1f, "timestamp TimeMS Roll Pitch Yaw VN VE VD PN PE PD GX GY GZ\n"); fprintf(ekf2f, "timestamp TimeMS AX AY AZ VWN VWE MN ME MD MX MY MZ\n"); fprintf(ekf3f, "timestamp TimeMS IVN IVE IVD IPN IPE IPD IMX IMY IMZ IVT\n"); fprintf(ekf4f, "timestamp TimeMS SV SP SH SMX SMY SMZ SVT OFN EFE FS DS\n"); }
bool LogReader::StrEntry::process(LogReader &a_logReader, bool a_init) { if (m_resume < 0) return false; const __int64 l_fileSize = a_logReader.m_fileSize; const unsigned int l_maxFindSize = a_logReader.m_maxFindSize; while (true) { NewlineType l_newlineType; const __int64 l_found = a_logReader.findNewline(m_resume, l_fileSize, l_newlineType); if (l_found < 0) { const __int64 l_testClose = l_fileSize - l_maxFindSize; if (m_resume < l_testClose) m_resume = l_fileSize; m_next->m_resume = m_resume; a_logReader.m_maxClose = l_fileSize; a_logReader.m_findEntry = m_resume; if (m_resume >= l_fileSize) m_resume = _I64_MIN; else m_resume = l_fileSize; return true; } else { const __int64 l_testClose = l_found - l_maxFindSize; if (m_resume >= l_testClose) { m_next->m_resume = m_resume; a_logReader.m_maxClose = l_found; a_logReader.m_findEntry = m_resume; if (l_newlineType == nt_crlf) m_resume = l_found + 2; else m_resume = l_found + 1; return true; } if (l_newlineType == nt_crlf) m_resume = l_found + 2; else m_resume = l_found + 1; } } return false; }
/* setup user -p parameters */ void Replay::set_user_parameters(void) { for (uint8_t i=0; i<num_user_parameters; i++) { if (!logreader.set_parameter(user_parameters[i].name, user_parameters[i].value)) { ::printf("Failed to set parameter %s to %f\n", user_parameters[i].name, user_parameters[i].value); exit(1); } } }
int main() { DMSClient client; LogReader reader; reader.setLogfile("wtmpx"); LogNetSender sender; sender.setServerip("127.0.0.1"); sender.setPort(9999); client.setReader(&reader); client.setSender(&sender); try { client.mine(); }catch(DMSException e) { cout<<e.what()<<endl; } return 0; }
void MyThread::run(){ /*把发送的数据 通知给界面*/ LogReader logreader; list<MatchedLogRec> matches=logreader.readLogs(); LogSender logsender; // logsender.sendMatches(&matches); /*让界面显示具体发送了那些数据*/ logsender.initNetWork(); /*循环发送数据*/ while(matches.size()>0){ char datastr[200]={0}; if(!logsender.sendMatche(*(matches.begin()))){ break; } /*把发送成功的数据通知界面*/ sprintf(datastr,"%s:%d:%s",matches.begin()->username,matches.begin()->pid,matches.begin()->logip); emit mySig(QString(datastr)); matches.erase(matches.begin()); sleep(1); } }
bool LogReader::Sample::process(LogReader &a_logReader, bool a_init) { if (!a_init) return false; const __int64 l_maxEntry = a_logReader.m_maxClose - m_dataSize; if (m_resume > l_maxEntry) return false; const __int64 l_close = m_resume + m_dataSize; const bool l_same = a_logReader.compare(m_resume, l_close, m_data); if (a_logReader.m_status != s_ok || !l_same) return false; if (m_next != InvPtr) m_next->m_resume = l_close; a_logReader.m_findClose = l_close; return true; }
/* check current solution against CHEK message */ void Replay::log_check_solution(void) { const LR_MsgHandler::CheckState &check_state = logreader.get_check_state(); Vector3f euler; Vector3f velocity; Location loc {}; _vehicle.EKF.getEulerAngles(euler); _vehicle.EKF.getVelNED(velocity); _vehicle.EKF.getLLH(loc); float roll_error = degrees(fabsf(euler.x - check_state.euler.x)); float pitch_error = degrees(fabsf(euler.y - check_state.euler.y)); float yaw_error = wrap_180_cd(100*degrees(fabsf(euler.z - check_state.euler.z)))*0.01f; float vel_error = (velocity - check_state.velocity).length(); float pos_error = get_distance(check_state.pos, loc); check_result.max_roll_error = MAX(check_result.max_roll_error, roll_error); check_result.max_pitch_error = MAX(check_result.max_pitch_error, pitch_error); check_result.max_yaw_error = MAX(check_result.max_yaw_error, yaw_error); check_result.max_vel_error = MAX(check_result.max_vel_error, vel_error); check_result.max_pos_error = MAX(check_result.max_pos_error, pos_error); }
void Replay::loop() { while (true) { char type[5]; if (arm_time_ms >= 0 && AP_HAL::millis() > (uint32_t)arm_time_ms) { if (!hal.util->get_soft_armed()) { hal.util->set_soft_armed(true); ::printf("Arming at %u ms\n", (unsigned)AP_HAL::millis()); } } if (!logreader.update(type)) { ::printf("End of log at %.1f seconds\n", AP_HAL::millis()*0.001f); fclose(plotf); break; } read_sensors(type); if (streq(type,"ATT")) { Vector3f ekf_euler; Vector3f velNED; Vector3f posNED; Vector3f gyroBias; float accelWeighting; float accelZBias1; float accelZBias2; Vector3f windVel; Vector3f magNED; Vector3f magXYZ; Vector3f DCM_attitude; Vector3f ekf_relpos; Vector3f velInnov; Vector3f posInnov; Vector3f magInnov; float tasInnov; float velVar; float posVar; float hgtVar; Vector3f magVar; float tasVar; Vector2f offset; uint16_t faultStatus; const Matrix3f &dcm_matrix = _vehicle.ahrs.AP_AHRS_DCM::get_rotation_body_to_ned(); dcm_matrix.to_euler(&DCM_attitude.x, &DCM_attitude.y, &DCM_attitude.z); _vehicle.EKF.getEulerAngles(ekf_euler); _vehicle.EKF.getVelNED(velNED); _vehicle.EKF.getPosNED(posNED); _vehicle.EKF.getGyroBias(gyroBias); _vehicle.EKF.getIMU1Weighting(accelWeighting); _vehicle.EKF.getAccelZBias(accelZBias1, accelZBias2); _vehicle.EKF.getWind(windVel); _vehicle.EKF.getMagNED(magNED); _vehicle.EKF.getMagXYZ(magXYZ); _vehicle.EKF.getInnovations(velInnov, posInnov, magInnov, tasInnov); _vehicle.EKF.getVariances(velVar, posVar, hgtVar, magVar, tasVar, offset); _vehicle.EKF.getFilterFaults(faultStatus); _vehicle.EKF.getPosNED(ekf_relpos); Vector3f inav_pos = _vehicle.inertial_nav.get_position() * 0.01f; float temp = degrees(ekf_euler.z); if (temp < 0.0f) temp = temp + 360.0f; fprintf(plotf, "%.3f %.1f %.1f %.1f %.2f %.1f %.1f %.1f %.2f %.2f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.2f %.2f %.2f %.2f %.2f %.2f\n", AP_HAL::millis() * 0.001f, logreader.get_sim_attitude().x, logreader.get_sim_attitude().y, logreader.get_sim_attitude().z, _vehicle.barometer.get_altitude(), logreader.get_attitude().x, logreader.get_attitude().y, wrap_180_cd(logreader.get_attitude().z*100)*0.01f, logreader.get_inavpos().x, logreader.get_inavpos().y, logreader.get_ahr2_attitude().x, logreader.get_ahr2_attitude().y, wrap_180_cd(logreader.get_ahr2_attitude().z*100)*0.01f, degrees(DCM_attitude.x), degrees(DCM_attitude.y), degrees(DCM_attitude.z), degrees(ekf_euler.x), degrees(ekf_euler.y), degrees(ekf_euler.z), inav_pos.x, inav_pos.y, inav_pos.z, ekf_relpos.x, ekf_relpos.y, -ekf_relpos.z); fprintf(plotf2, "%.3f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n", AP_HAL::millis() * 0.001f, degrees(ekf_euler.x), degrees(ekf_euler.y), temp, velNED.x, velNED.y, velNED.z, posNED.x, posNED.y, posNED.z, 60*degrees(gyroBias.x), 60*degrees(gyroBias.y), 60*degrees(gyroBias.z), windVel.x, windVel.y, magNED.x, magNED.y, magNED.z, magXYZ.x, magXYZ.y, magXYZ.z, logreader.get_attitude().x, logreader.get_attitude().y, logreader.get_attitude().z); // define messages for EKF1 data packet int16_t roll = (int16_t)(100*degrees(ekf_euler.x)); // roll angle (centi-deg) int16_t pitch = (int16_t)(100*degrees(ekf_euler.y)); // pitch angle (centi-deg) uint16_t yaw = (uint16_t)wrap_360_cd(100*degrees(ekf_euler.z)); // yaw angle (centi-deg) float velN = (float)(velNED.x); // velocity North (m/s) float velE = (float)(velNED.y); // velocity East (m/s) float velD = (float)(velNED.z); // velocity Down (m/s) float posN = (float)(posNED.x); // metres North float posE = (float)(posNED.y); // metres East float posD = (float)(posNED.z); // metres Down float gyrX = (float)(6000*degrees(gyroBias.x)); // centi-deg/min float gyrY = (float)(6000*degrees(gyroBias.y)); // centi-deg/min float gyrZ = (float)(6000*degrees(gyroBias.z)); // centi-deg/min // print EKF1 data packet fprintf(ekf1f, "%.3f %u %d %d %u %.2f %.2f %.2f %.2f %.2f %.2f %.0f %.0f %.0f\n", AP_HAL::millis() * 0.001f, AP_HAL::millis(), roll, pitch, yaw, velN, velE, velD, posN, posE, posD, gyrX, gyrY, gyrZ); // define messages for EKF2 data packet int8_t accWeight = (int8_t)(100*accelWeighting); int8_t acc1 = (int8_t)(100*accelZBias1); int8_t acc2 = (int8_t)(100*accelZBias2); int16_t windN = (int16_t)(100*windVel.x); int16_t windE = (int16_t)(100*windVel.y); int16_t magN = (int16_t)(magNED.x); int16_t magE = (int16_t)(magNED.y); int16_t magD = (int16_t)(magNED.z); int16_t magX = (int16_t)(magXYZ.x); int16_t magY = (int16_t)(magXYZ.y); int16_t magZ = (int16_t)(magXYZ.z); // print EKF2 data packet fprintf(ekf2f, "%.3f %d %d %d %d %d %d %d %d %d %d %d %d\n", AP_HAL::millis() * 0.001f, AP_HAL::millis(), accWeight, acc1, acc2, windN, windE, magN, magE, magD, magX, magY, magZ); // define messages for EKF3 data packet int16_t innovVN = (int16_t)(100*velInnov.x); int16_t innovVE = (int16_t)(100*velInnov.y); int16_t innovVD = (int16_t)(100*velInnov.z); int16_t innovPN = (int16_t)(100*posInnov.x); int16_t innovPE = (int16_t)(100*posInnov.y); int16_t innovPD = (int16_t)(100*posInnov.z); int16_t innovMX = (int16_t)(magInnov.x); int16_t innovMY = (int16_t)(magInnov.y); int16_t innovMZ = (int16_t)(magInnov.z); int16_t innovVT = (int16_t)(100*tasInnov); // print EKF3 data packet fprintf(ekf3f, "%.3f %d %d %d %d %d %d %d %d %d %d %d\n", AP_HAL::millis() * 0.001f, AP_HAL::millis(), innovVN, innovVE, innovVD, innovPN, innovPE, innovPD, innovMX, innovMY, innovMZ, innovVT); // define messages for EKF4 data packet int16_t sqrtvarV = (int16_t)(constrain_float(100*velVar,INT16_MIN,INT16_MAX)); int16_t sqrtvarP = (int16_t)(constrain_float(100*posVar,INT16_MIN,INT16_MAX)); int16_t sqrtvarH = (int16_t)(constrain_float(100*hgtVar,INT16_MIN,INT16_MAX)); int16_t sqrtvarMX = (int16_t)(constrain_float(100*magVar.x,INT16_MIN,INT16_MAX)); int16_t sqrtvarMY = (int16_t)(constrain_float(100*magVar.y,INT16_MIN,INT16_MAX)); int16_t sqrtvarMZ = (int16_t)(constrain_float(100*magVar.z,INT16_MIN,INT16_MAX)); int16_t sqrtvarVT = (int16_t)(constrain_float(100*tasVar,INT16_MIN,INT16_MAX)); int16_t offsetNorth = (int8_t)(constrain_float(offset.x,INT16_MIN,INT16_MAX)); int16_t offsetEast = (int8_t)(constrain_float(offset.y,INT16_MIN,INT16_MAX)); // print EKF4 data packet fprintf(ekf4f, "%.3f %u %d %d %d %d %d %d %d %d %d %d\n", AP_HAL::millis() * 0.001f, (unsigned)AP_HAL::millis(), (int)sqrtvarV, (int)sqrtvarP, (int)sqrtvarH, (int)sqrtvarMX, (int)sqrtvarMY, (int)sqrtvarMZ, (int)sqrtvarVT, (int)offsetNorth, (int)offsetEast, (int)faultStatus); } } flush_dataflash(); if (check_solution) { report_checks(); } exit(0); }
void Replay::_parse_command_line(uint8_t argc, char * const argv[]) { const struct GetOptLong::option options[] = { {"parm", true, 0, 'p'}, {"param", true, 0, 'p'}, {"help", false, 0, 'h'}, {"accel-mask", true, 0, 'a'}, {"gyro-mask", true, 0, 'g'}, {"arm-time", true, 0, 'A'}, {"no-imt", false, 0, 'n'}, {"check-generate", false, 0, OPT_CHECK_GENERATE}, {"check", false, 0, OPT_CHECK}, {"tolerance-euler", true, 0, OPT_TOLERANCE_EULER}, {"tolerance-pos", true, 0, OPT_TOLERANCE_POS}, {"tolerance-vel", true, 0, OPT_TOLERANCE_VEL}, {"nottypes", true, 0, OPT_NOTTYPES}, {"downsample", true, 0, OPT_DOWNSAMPLE}, {"logmatch", false, 0, OPT_LOGMATCH}, {"no-params", false, 0, OPT_NOPARAMS}, {0, false, 0, 0} }; GetOptLong gopt(argc, argv, "r:p:ha:g:A:", options); int opt; while ((opt = gopt.getoption()) != -1) { switch (opt) { case 'g': logreader.set_gyro_mask(strtol(gopt.optarg, NULL, 0)); break; case 'a': logreader.set_accel_mask(strtol(gopt.optarg, NULL, 0)); break; case 'A': arm_time_ms = strtol(gopt.optarg, NULL, 0); break; case 'n': use_imt = false; logreader.set_use_imt(use_imt); break; case 'p': { const char *eq = strchr(gopt.optarg, '='); if (eq == NULL) { ::printf("Usage: -p NAME=VALUE\n"); exit(1); } memset(user_parameters[num_user_parameters].name, '\0', 16); strncpy(user_parameters[num_user_parameters].name, gopt.optarg, eq-gopt.optarg); user_parameters[num_user_parameters].value = atof(eq+1); num_user_parameters++; if (num_user_parameters >= ARRAY_SIZE(user_parameters)) { ::printf("Too many user parameters\n"); exit(1); } break; } case OPT_CHECK_GENERATE: check_generate = true; break; case OPT_CHECK: check_solution = true; break; case OPT_TOLERANCE_EULER: tolerance_euler = atof(gopt.optarg); break; case OPT_TOLERANCE_POS: tolerance_pos = atof(gopt.optarg); break; case OPT_TOLERANCE_VEL: tolerance_vel = atof(gopt.optarg); break; case OPT_NOTTYPES: nottypes = parse_list_from_string(gopt.optarg); break; case OPT_DOWNSAMPLE: downsample = atoi(gopt.optarg); break; case OPT_LOGMATCH: logmatch = true; break; case OPT_NOPARAMS: globals.no_params = true; break; case 'h': default: usage(); exit(0); } } argv += gopt.optind; argc -= gopt.optind; if (argc > 0) { filename = argv[0]; } }
void Replay::setup() { ::printf("Starting\n"); uint8_t argc; char * const *argv; hal.util->commandline_arguments(argc, argv); _parse_command_line(argc, argv); // _parse_command_line sets up an FPE handler. We can do better: signal(SIGFPE, _replay_sig_fpe); hal.console->printf("Processing log %s\n", filename); if (update_rate == 0) { update_rate = find_update_rate(filename); } hal.console->printf("Using an update rate of %u Hz\n", update_rate); if (!logreader.open_log(filename)) { perror(filename); exit(1); } _vehicle.setup(); set_ins_update_rate(update_rate); logreader.wait_type("GPS"); logreader.wait_type("IMU"); logreader.wait_type("GPS"); logreader.wait_type("IMU"); feenableexcept(FE_INVALID | FE_OVERFLOW); plotf = fopen("plot.dat", "w"); plotf2 = fopen("plot2.dat", "w"); ekf1f = fopen("EKF1.dat", "w"); ekf2f = fopen("EKF2.dat", "w"); ekf3f = fopen("EKF3.dat", "w"); ekf4f = fopen("EKF4.dat", "w"); fprintf(plotf, "time SIM.Roll SIM.Pitch SIM.Yaw BAR.Alt FLIGHT.Roll FLIGHT.Pitch FLIGHT.Yaw FLIGHT.dN FLIGHT.dE FLIGHT.Alt AHR2.Roll AHR2.Pitch AHR2.Yaw DCM.Roll DCM.Pitch DCM.Yaw EKF.Roll EKF.Pitch EKF.Yaw INAV.dN INAV.dE INAV.Alt EKF.dN EKF.dE EKF.Alt\n"); fprintf(plotf2, "time E1 E2 E3 VN VE VD PN PE PD GX GY GZ WN WE MN ME MD MX MY MZ E1ref E2ref E3ref\n"); fprintf(ekf1f, "timestamp TimeMS Roll Pitch Yaw VN VE VD PN PE PD GX GY GZ\n"); fprintf(ekf2f, "timestamp TimeMS AX AY AZ VWN VWE MN ME MD MX MY MZ\n"); fprintf(ekf3f, "timestamp TimeMS IVN IVE IVD IPN IPE IPD IMX IMY IMZ IVT\n"); fprintf(ekf4f, "timestamp TimeMS SV SP SH SMX SMY SMZ SVT OFN EFE FS DS\n"); ::printf("Waiting for GPS\n"); while (!done_home_init) { char type[5]; if (!logreader.update(type)) { break; } read_sensors(type); if (streq(type, "GPS") && (_vehicle.gps.status() >= AP_GPS::GPS_OK_FIX_3D) && done_baro_init && !done_home_init) { const Location &loc = _vehicle.gps.location(); ::printf("GPS Lock at %.7f %.7f %.2fm time=%.1f seconds\n", loc.lat * 1.0e-7f, loc.lng * 1.0e-7f, loc.alt * 0.01f, hal.scheduler->millis()*0.001f); _vehicle.ahrs.set_home(loc); _vehicle.compass.set_initial_location(loc.lat, loc.lng); done_home_init = true; } } }
// Foreground waits for exit of the main persistent threads // that are started here. The threads are created to manage // UNIX domain client sockets for writing, reading and // controlling the user space logger, and for any additional // logging plugins like auditd and restart control. Additional // transitory per-client threads are created for each reader. int main(int argc, char *argv[]) { fdDmesg = open("/dev/kmsg", O_WRONLY); // issue reinit command. KISS argument parsing. if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { int sock = TEMP_FAILURE_RETRY( socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM)); if (sock < 0) { return -errno; } static const char reinit[] = "reinit"; ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinit, sizeof(reinit))); if (ret < 0) { return -errno; } struct pollfd p; memset(&p, 0, sizeof(p)); p.fd = sock; p.events = POLLIN; ret = TEMP_FAILURE_RETRY(poll(&p, 1, 100)); if (ret < 0) { return -errno; } if ((ret == 0) || !(p.revents & POLLIN)) { return -ETIME; } static const char success[] = "success"; char buffer[sizeof(success) - 1]; memset(buffer, 0, sizeof(buffer)); ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); if (ret < 0) { return -errno; } return strncmp(buffer, success, sizeof(success) - 1) != 0; } // Reinit Thread sem_init(&reinit, 0, 0); sem_init(&uidName, 0, 0); pthread_attr_t attr; if (!pthread_attr_init(&attr)) { struct sched_param param; memset(¶m, 0, sizeof(param)); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setschedpolicy(&attr, SCHED_BATCH); if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { pthread_t thread; reinit_running = true; if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) { reinit_running = false; } } pthread_attr_destroy(&attr); } if (drop_privs() != 0) { return -1; } // Serves the purpose of managing the last logs times read on a // socket connection, and as a reader lock on a range of log // entries. LastLogTimes *times = new LastLogTimes(); // LogBuffer is the object which is responsible for holding all // log entries. logBuf = new LogBuffer(times); signal(SIGHUP, reinit_signal_handler); { char property[PROPERTY_VALUE_MAX]; property_get("ro.build.type", property, ""); if (property_get_bool("logd.statistics", !!strcmp(property, "user") && !property_get_bool("ro.config.low_ram", false))) { logBuf->enableStatistics(); } } // LogReader listens on /dev/socket/logdr. When a client // connects, log entries in the LogBuffer are written to the client. LogReader *reader = new LogReader(logBuf); if (reader->startListener()) { exit(1); } // LogListener listens on /dev/socket/logdw for client // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. LogListener *swl = new LogListener(logBuf, reader); // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value if (swl->startListener(300)) { exit(1); } // Command listener listens on /dev/socket/logd for incoming logd // administrative commands. CommandListener *cl = new CommandListener(logBuf, reader, swl); if (cl->startListener()) { exit(1); } // LogAudit listens on NETLINK_AUDIT socket for selinux // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. bool auditd = property_get_bool("logd.auditd", true); if (auditd) { bool dmesg = property_get_bool("logd.auditd.dmesg", true); // failure is an option ... messages are in dmesg (required by standard) LogAudit *al = new LogAudit(logBuf, reader, dmesg ? fdDmesg : -1); int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0); if (len > 0) { len++; char buf[len]; int rc = klogctl(KLOG_READ_ALL, buf, len); if (rc >= 0) { buf[len - 1] = '\0'; for (char *ptr, *tok = buf; (tok = strtok_r(tok, "\r\n", &ptr)); tok = NULL) { al->log(tok); } } } if (al->startListener()) { delete al; } } TEMP_FAILURE_RETRY(pause()); exit(0); }
DWORD WINAPI LolSceneSwitch::MonitorThread(_In_ LPVOID lpParam) { LolSceneSwitch * instance = static_cast<LolSceneSwitch *>(lpParam); unsigned int const INTERVALL = instance->settings.intervall; // Handles etc. for the client HANDLE clientProcess = nullptr; HWND clientWindow = nullptr; DWORD clientPid = 0; // Handles etc. for the game HANDLE gameProcess = nullptr; HWND gameWindow = nullptr; DWORD gamePid; FILETIME gameStartTime; // temp var for saving the exit code DWORD exitCode; // Used to read the log file LogReader * reader = nullptr; // Stuff for reading memory PointerPath32 clienStatePointer({ -0x658, 0x78, 0x610, 0x4, 0xe48 }); PointerPath32 map1Pointer({ -0x9C0, 0x20 }); PointerPath32 map2Pointer({ -0x9C4, 0x20 }); DWORD clientStateAddress = 0; long clientState = 0; DWORD mapAddress = 0; // info variables of the state of LoL bool ingame = false; bool postGame = false; State state = State::CLIENTOUT; State oldState = State::CLIENTOUT; bool newMapInfo = false; // The main loop for monitoring LoL while (instance->runMonitoring) { // Try to get handles for the client and game process if (clientProcess == nullptr) { clientProcess = GetProcessByName(TEXT("LolClient.exe"), clientPid); } if (gameProcess == nullptr) { gameProcess = GetProcessByName(TEXT("League of Legends.exe"), gamePid); if (gameProcess != nullptr) { ingame = true; FILETIME temp; GetProcessTimes(gameProcess, &gameStartTime, &temp, &temp, &temp); } } // We have a client handle if (clientProcess != nullptr) { // check if it's still running if (GetExitCodeProcess(clientProcess, &exitCode) && exitCode == STILL_ACTIVE) { if (clientWindow == nullptr) { clientWindow = GetWindowById(clientPid); } if (clientStateAddress == 0) { clientStateAddress = PointerPath32::GetThreadAddress(clientProcess, clientPid, 0); } if (!ingame) { if (instance->settings.scenes[State::CLIENTOUT].single.IsEmpty() || (clientWindow != nullptr && HasFocus(clientWindow))) { if (clienStatePointer.Deref(clientProcess, clientStateAddress, clientState) && clientState == 1) { if (postGame) { state = State::POSTGAME; } else { state = State::CHAMPSELECT; } } else { postGame = false; state = State::CLIENT; } } else { state = State::CLIENTOUT; } } } else { Log("INFO | LolSceneSwitch::MonitorThread | LoL client process exited!"); CloseHandle(clientProcess); clientProcess = nullptr; clientWindow = nullptr; clientStateAddress = 0; } } // we have a game handle if (gameProcess != nullptr) { // check if it's still running if (GetExitCodeProcess(gameProcess, &exitCode) && exitCode == STILL_ACTIVE) { if (gameWindow == nullptr) { gameWindow = GetWindowById(gamePid); } if (reader == nullptr) { HANDLE file = GetLogFile(instance->settings.lolPath, &gameStartTime); if (file != nullptr) { reader = &LogReader(file); } } if (mapAddress == 0) { mapAddress = PointerPath32::GetThreadAddress(gameProcess, gamePid, 0); } if (instance->currentMap == Map::UNKNOWN) { std::string mapString1 = map1Pointer.Deref(gameProcess, mapAddress, 5); std::string mapString2 = map2Pointer.Deref(gameProcess, mapAddress, 5); if (mapString1.compare("Map1") == 0 || mapString2.compare("Map1") == 0 || mapString1.compare("Map11") == 0 || mapString2.compare("Map11") == 0) { Log("INFO | LolSceneSwitch::MonitorThread | Map is Summoners Rift!"); instance->currentMap = Map::SUMMONERS_RIFT; newMapInfo = true; } else if (mapString1.compare("Map8") == 0 || mapString2.compare("Map8") == 0) { Log("INFO | LolSceneSwitch::MonitorThread | Map is Crystal Scar!"); instance->currentMap = Map::CRYSTAL_SCAR; newMapInfo = true; } else if (mapString1.compare("Map10") == 0 || mapString2.compare("Map10") == 0) { Log("INFO | LolSceneSwitch::MonitorThread | Map is Twisted Treeline!"); instance->currentMap = Map::TWISTED_TREELINE; newMapInfo = true; } else if (mapString1.compare("Map12") == 0 || mapString2.compare("Map12") == 0) { Log("INFO | LolSceneSwitch::MonitorThread | Map is Howling Abyss!"); instance->currentMap = Map::HOWLING_ABYSS; newMapInfo = true; } } if (reader != nullptr && (instance->settings.scenes[State::GAMEOUT].single.IsEmpty() || (gameWindow != nullptr && HasFocus(gameWindow)))) { state = reader->GetState(); } else { state = State::GAMEOUT; } } else { Log("INFO | LolSceneSwitch::MonitorThread | LoL game process exited!"); ingame = false; postGame = true; CloseHandle(gameProcess); gameProcess = nullptr; gameWindow = nullptr; reader = nullptr; instance->currentMap = Map::UNKNOWN; mapAddress = 0; } } if (state != oldState || newMapInfo) { // Something has changed!!! Log("INFO | LolSceneSwitch::MonitorThread | New state:", static_cast<long long>(state)); oldState = state; newMapInfo = false; instance->ChangeScene(state); } Sleep(INTERVALL); } return 0; }
bool LogReader::Substit::process(LogReader &a_logReader, bool a_init) { if (m_resume < 0) return false; const __int64 l_fileSize = a_logReader.m_fileSize; const unsigned int l_maxFindSize = a_logReader.m_maxFindSize; __int64 &l_maxClose = a_logReader.m_maxClose; const __int64 l_testClose = l_fileSize - l_maxFindSize; if (m_prev == InvPtr) { if (m_resume >= l_testClose) l_maxClose = l_fileSize; else l_maxClose = m_resume + l_maxFindSize; } const __int64 l_maxEntry = l_maxClose - m_singles; if (m_resume > l_maxEntry) return false; if (m_anySeq) { if (m_next != InvPtr && m_next->type() == t_sample) { const Sample *const l_next = static_cast<const Sample *>(m_next); const char l_firstChar = l_next->m_data[0]; const __int64 l_minClose = m_resume + m_singles; if (m_prev == InvPtr) { const __int64 l_found = a_logReader.find(l_minClose, l_fileSize, l_firstChar); if (a_logReader.m_status != s_ok || l_found < 0) return false; m_resume = l_found - m_singles; if (m_resume >= l_testClose) l_maxClose = l_fileSize; else l_maxClose = m_resume + l_maxFindSize; } else { const __int64 l_found = a_logReader.find(l_minClose, l_maxClose, l_firstChar); if (a_logReader.m_status != s_ok || l_found < 0) return false; m_resume = l_found - m_singles; } } } else if (!a_init) return false; const __int64 l_close = m_resume + m_singles; if (m_prev == InvPtr) a_logReader.m_findEntry = m_resume; if (m_next != InvPtr) m_next->m_resume = l_close; a_logReader.m_findClose = l_close; m_resume++; return true; }
// Foreground waits for exit of the main persistent threads // that are started here. The threads are created to manage // UNIX domain client sockets for writing, reading and // controlling the user space logger, and for any additional // logging plugins like auditd and restart control. Additional // transitory per-client threads are created for each reader. int main(int argc, char *argv[]) { int fdPmesg = -1; bool klogd = property_get_bool("logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE); if (klogd) { fdPmesg = open("/proc/kmsg", O_RDONLY | O_NDELAY); } fdDmesg = open("/dev/kmsg", O_WRONLY); // issue reinit command. KISS argument parsing. if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { int sock = TEMP_FAILURE_RETRY( socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM)); if (sock < 0) { return -errno; } static const char reinit[] = "reinit"; ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinit, sizeof(reinit))); if (ret < 0) { return -errno; } struct pollfd p; memset(&p, 0, sizeof(p)); p.fd = sock; p.events = POLLIN; ret = TEMP_FAILURE_RETRY(poll(&p, 1, 1000)); if (ret < 0) { return -errno; } if ((ret == 0) || !(p.revents & POLLIN)) { return -ETIME; } static const char success[] = "success"; char buffer[sizeof(success) - 1]; memset(buffer, 0, sizeof(buffer)); ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); if (ret < 0) { return -errno; } return strncmp(buffer, success, sizeof(success) - 1) != 0; } // Reinit Thread sem_init(&reinit, 0, 0); sem_init(&uidName, 0, 0); sem_init(&sem_name, 0, 1); pthread_attr_t attr; if (!pthread_attr_init(&attr)) { struct sched_param param; memset(¶m, 0, sizeof(param)); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setschedpolicy(&attr, SCHED_BATCH); if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { pthread_t thread; reinit_running = true; if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) { reinit_running = false; } } pthread_attr_destroy(&attr); } if (drop_privs() != 0) { return -1; } // Serves the purpose of managing the last logs times read on a // socket connection, and as a reader lock on a range of log // entries. LastLogTimes *times = new LastLogTimes(); // LogBuffer is the object which is responsible for holding all // log entries. logBuf = new LogBuffer(times); signal(SIGHUP, reinit_signal_handler); if (property_get_bool("logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE)) { logBuf->enableStatistics(); } // LogReader listens on /dev/socket/logdr. When a client // connects, log entries in the LogBuffer are written to the client. LogReader *reader = new LogReader(logBuf); if (reader->startListener()) { exit(1); } // LogListener listens on /dev/socket/logdw for client // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. LogListener *swl = new LogListener(logBuf, reader); // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value if (swl->startListener(600)) { exit(1); } // Command listener listens on /dev/socket/logd for incoming logd // administrative commands. CommandListener *cl = new CommandListener(logBuf, reader, swl); if (cl->startListener()) { exit(1); } // LogAudit listens on NETLINK_AUDIT socket for selinux // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. bool auditd = property_get_bool("logd.auditd", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST); LogAudit *al = NULL; if (auditd) { al = new LogAudit(logBuf, reader, property_get_bool("logd.auditd.dmesg", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST) ? fdDmesg : -1); } LogKlog *kl = NULL; if (klogd) { kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != NULL); } readDmesg(al, kl); // failure is an option ... messages are in dmesg (required by standard) if (kl && kl->startListener()) { delete kl; } if (al && al->startListener()) { delete al; } TEMP_FAILURE_RETRY(pause()); exit(0); }
// Foreground waits for exit of the main persistent threads // that are started here. The threads are created to manage // UNIX domain client sockets for writing, reading and // controlling the user space logger, and for any additional // logging plugins like auditd and restart control. Additional // transitory per-client threads are created for each reader. int main(int argc, char* argv[]) { // logd is written under the assumption that the timezone is UTC. // If TZ is not set, persist.sys.timezone is looked up in some time utility // libc functions, including mktime. It confuses the logd time handling, // so here explicitly set TZ to UTC, which overrides the property. setenv("TZ", "UTC", 1); // issue reinit command. KISS argument parsing. if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { return issueReinit(); } static const char dev_kmsg[] = "/dev/kmsg"; fdDmesg = android_get_control_file(dev_kmsg); if (fdDmesg < 0) { fdDmesg = TEMP_FAILURE_RETRY(open(dev_kmsg, O_WRONLY | O_CLOEXEC)); } int fdPmesg = -1; bool klogd = __android_logger_property_get_bool( "logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE); if (klogd) { static const char proc_kmsg[] = "/proc/kmsg"; fdPmesg = android_get_control_file(proc_kmsg); if (fdPmesg < 0) { fdPmesg = TEMP_FAILURE_RETRY( open(proc_kmsg, O_RDONLY | O_NDELAY | O_CLOEXEC)); } if (fdPmesg < 0) android::prdebug("Failed to open %s\n", proc_kmsg); } // Reinit Thread sem_init(&reinit, 0, 0); sem_init(&uidName, 0, 0); sem_init(&sem_name, 0, 1); pthread_attr_t attr; if (!pthread_attr_init(&attr)) { struct sched_param param; memset(¶m, 0, sizeof(param)); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setschedpolicy(&attr, SCHED_BATCH); if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { pthread_t thread; reinit_running = true; if (pthread_create(&thread, &attr, reinit_thread_start, nullptr)) { reinit_running = false; } } pthread_attr_destroy(&attr); } bool auditd = __android_logger_property_get_bool("ro.logd.auditd", BOOL_DEFAULT_TRUE); if (drop_privs(klogd, auditd) != 0) { return -1; } // Serves the purpose of managing the last logs times read on a // socket connection, and as a reader lock on a range of log // entries. LastLogTimes* times = new LastLogTimes(); // LogBuffer is the object which is responsible for holding all // log entries. logBuf = new LogBuffer(times); signal(SIGHUP, reinit_signal_handler); if (__android_logger_property_get_bool( "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE)) { logBuf->enableStatistics(); } // LogReader listens on /dev/socket/logdr. When a client // connects, log entries in the LogBuffer are written to the client. LogReader* reader = new LogReader(logBuf); if (reader->startListener()) { exit(1); } // LogListener listens on /dev/socket/logdw for client // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. LogListener* swl = new LogListener(logBuf, reader); // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value if (swl->startListener(600)) { exit(1); } // Command listener listens on /dev/socket/logd for incoming logd // administrative commands. CommandListener* cl = new CommandListener(logBuf, reader, swl); if (cl->startListener()) { exit(1); } // LogAudit listens on NETLINK_AUDIT socket for selinux // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. LogAudit* al = nullptr; if (auditd) { al = new LogAudit(logBuf, reader, __android_logger_property_get_bool( "ro.logd.auditd.dmesg", BOOL_DEFAULT_TRUE) ? fdDmesg : -1); } LogKlog* kl = nullptr; if (klogd) { kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != nullptr); } readDmesg(al, kl); // failure is an option ... messages are in dmesg (required by standard) if (kl && kl->startListener()) { delete kl; } if (al && al->startListener()) { delete al; } TEMP_FAILURE_RETRY(pause()); exit(0); }
// Foreground waits for exit of the three main persistent threads that // are started here. The three threads are created to manage UNIX // domain client sockets for writing, reading and controlling the user // space logger. Additional transitory per-client threads are created // for each reader once they register. int main() { int fdDmesg = -1; char dmesg[PROPERTY_VALUE_MAX]; property_get("logd.auditd.dmesg", dmesg, "1"); if (atol(dmesg)) { fdDmesg = open("/dev/kmsg", O_WRONLY); } if (drop_privs() != 0) { return -1; } // Serves the purpose of managing the last logs times read on a // socket connection, and as a reader lock on a range of log // entries. LastLogTimes *times = new LastLogTimes(); // LogBuffer is the object which is responsible for holding all // log entries. LogBuffer *logBuf = new LogBuffer(times); char dgram_qlen_statistics[PROPERTY_VALUE_MAX]; property_get("logd.dgram_qlen.statistics", dgram_qlen_statistics, ""); if (atol(dgram_qlen_statistics)) { logBuf->enableDgramQlenStatistics(); } // LogReader listens on /dev/socket/logdr. When a client // connects, log entries in the LogBuffer are written to the client. LogReader *reader = new LogReader(logBuf); if (reader->startListener()) { exit(1); } // LogListener listens on /dev/socket/logdw for client // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. LogListener *swl = new LogListener(logBuf, reader); // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value if (swl->startListener(300)) { exit(1); } // Command listener listens on /dev/socket/logd for incoming logd // administrative commands. CommandListener *cl = new CommandListener(logBuf, reader, swl); if (cl->startListener()) { exit(1); } // LogAudit listens on NETLINK_AUDIT socket for selinux // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. // failure is an option ... messages are in dmesg (required by standard) LogAudit *al = new LogAudit(logBuf, reader, fdDmesg); if (al->startListener()) { delete al; close(fdDmesg); } pause(); exit(0); }