示例#1
0
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);
}
示例#2
0
int main(){
    LogReader  logreader;
    LogSender  logsender;
    list<MatchedLogRec>  matches=
    logreader.readLogs();
    logsender.sendMatches(&matches);
}
示例#3
0
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;

	}
示例#5
0
/*
  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);
        }
    }
}
示例#6
0
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;
}
示例#7
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;

	}
示例#9
0
/*
  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);
}
示例#10
0
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);
}
示例#11
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];
    }
}
示例#12
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;
        }
    }
}
示例#13
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[]) {
    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(&param, 0, sizeof(param));
        pthread_attr_setschedparam(&attr, &param);
        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);
}
示例#14
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;

	}
示例#16
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[]) {
    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(&param, 0, sizeof(param));
        pthread_attr_setschedparam(&attr, &param);
        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);
}
示例#17
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(&param, 0, sizeof(param));
        pthread_attr_setschedparam(&attr, &param);
        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);
}
示例#18
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);
}