<commit_before>#include "dataflash_logger.h"

#include <signal.h>
#include <stdio.h> // for snprintf
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

#include "la-log.h"
#include "util.h"
#include "mavlink_c_library/common/mavlink.h"

void DataFlash_Logger::sighup_received()
{
    logging_stop();
}

void DataFlash_Logger::idle_tenthHz()
{
    // the following isn't quite right given we seek around...
    if (logging_started) {
	la_log(LOG_INFO, "mh-dfl: Current log size: %lu", lseek(out_fd, 0, SEEK_CUR));
    }
}

void DataFlash_Logger::idle_1Hz()
{
   if (!logging_started) {
       if (sender_system_id != 0) {
	   // we've previously been logging, so telling the other end
	   // to stop logging may let us restart logging sooner
	   send_stop_logging_packet();
       }
       send_start_logging_packet();
   }
}
void DataFlash_Logger::idle_10Hz()
{
    if (logging_started) {
	// if no data packet in 10 seconds then close log
        uint64_t now_us = clock_gettime_us(CLOCK_MONOTONIC);
	if (now_us - _last_data_packet_time > 10000000) {
	    la_log(LOG_INFO, "mh-dfl: No data packets received for some time (now=%llu last=%llu).  Closing log.  Final log size: %lu", now_us,_last_data_packet_time, lseek(out_fd, 0, SEEK_CUR));
	    logging_stop();
	}
    }
}

void DataFlash_Logger::idle_100Hz()
{
    push_response_queue();
}

void DataFlash_Logger::send_response(uint32_t seqno, bool status) {
    mavlink_message_t msg;
    mavlink_msg_remote_log_block_status_pack(this_system_id, this_component_id, &msg, sender_system_id, sender_component_id, seqno, status);
    _mavlink_writer->send_message(msg);
}

void DataFlash_Logger::push_response_queue()
{
    const uint8_t max_packets_to_send = 5;
    uint8_t packets_sent = 0;
    while (response_queue_head != response_queue_tail &&
	   packets_sent < max_packets_to_send) {
	send_response(responses[response_queue_tail].seqno,
		      responses[response_queue_tail].status);
	response_queue_tail++;
	if (response_queue_tail >= RESPONSE_QUEUE_LENGTH) {
	    response_queue_tail = 0;
	}
    }
}

bool DataFlash_Logger::configure(INIReader *config)
{
    if (!MAVLink_Message_Handler::configure(config)) {
        return false;
    }

    std::string path = config->Get("dflogger", "log_dirpath", "/log/dataflash");
    _log_directory_path = strdup(path.c_str());
    if (_log_directory_path == NULL) {
	return false;
    }

    target_system_id = config->GetInteger("dflogger", "target_system_id", 0);
    target_component_id = config->GetInteger("dflogger", "target_component_id", 0);

    return true;
}

bool DataFlash_Logger::make_new_log_filename(char *buffer, uint8_t bufferlen)
{
  uint8_t lastlog_buflen = 128;
  char lastlog_buf[128];
    // this was really beautiful, but I don't think SoloLink has an
    // RTC; it depends on GPS to update its clock (scribbled down
    // periodically?)

    // time_t t;

    // time(&t);
    // struct tm *timebits = gmtime(&t);

    // snprintf(buffer, bufferlen, "%s/%04d%02d%02d%02d%02d%02d.BIN",
    //          _log_directory_path,
    //          timebits->tm_year+1900,
    //          timebits->tm_mon+1,
    //          timebits->tm_mday,
    //          timebits->tm_hour,
    //          timebits->tm_min,
    //          timebits->tm_sec);


    memset(lastlog_buf, '\0', lastlog_buflen);
    snprintf(lastlog_buf, lastlog_buflen, "%s/LASTLOG.TXT", _log_directory_path);<commit_msg>dataflash_logger: optionally take source_system_id and source_component_id from config file<commit_after>#include "dataflash_logger.h"

#include <signal.h>
#include <stdio.h> // for snprintf
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

#include "la-log.h"
#include "util.h"
#include "mavlink_c_library/common/mavlink.h"

void DataFlash_Logger::sighup_received()
{
    logging_stop();
}

void DataFlash_Logger::idle_tenthHz()
{
    // the following isn't quite right given we seek around...
    if (logging_started) {
	la_log(LOG_INFO, "mh-dfl: Current log size: %lu", lseek(out_fd, 0, SEEK_CUR));
    }
}

void DataFlash_Logger::idle_1Hz()
{
   if (!logging_started) {
       if (sender_system_id != 0) {
	   // we've previously been logging, so telling the other end
	   // to stop logging may let us restart logging sooner
	   send_stop_logging_packet();
       }
       send_start_logging_packet();
   }
}
void DataFlash_Logger::idle_10Hz()
{
    if (logging_started) {
	// if no data packet in 10 seconds then close log
        uint64_t now_us = clock_gettime_us(CLOCK_MONOTONIC);
	if (now_us - _last_data_packet_time > 10000000) {
	    la_log(LOG_INFO, "mh-dfl: No data packets received for some time (now=%llu last=%llu).  Closing log.  Final log size: %lu", now_us,_last_data_packet_time, lseek(out_fd, 0, SEEK_CUR));
	    logging_stop();
	}
    }
}

void DataFlash_Logger::idle_100Hz()
{
    push_response_queue();
}

void DataFlash_Logger::send_response(uint32_t seqno, bool status) {
    mavlink_message_t msg;
    mavlink_msg_remote_log_block_status_pack(this_system_id, this_component_id, &msg, sender_system_id, sender_component_id, seqno, status);
    _mavlink_writer->send_message(msg);
}

void DataFlash_Logger::push_response_queue()
{
    const uint8_t max_packets_to_send = 5;
    uint8_t packets_sent = 0;
    while (response_queue_head != response_queue_tail &&
	   packets_sent < max_packets_to_send) {
	send_response(responses[response_queue_tail].seqno,
		      responses[response_queue_tail].status);
	response_queue_tail++;
	if (response_queue_tail >= RESPONSE_QUEUE_LENGTH) {
	    response_queue_tail = 0;
	}
    }
}

bool DataFlash_Logger::configure(INIReader *config)
{
    if (!MAVLink_Message_Handler::configure(config)) {
        return false;
    }

    std::string path = config->Get("dflogger", "log_dirpath", "/log/dataflash");
    _log_directory_path = strdup(path.c_str());
    if (_log_directory_path == NULL) {
	return false;
    }

    this_system_id = config->GetInteger("dflogger", "source_system_id", this_system_id);
    this_component_id = config->GetInteger("dflogger", "source_component_id", this_component_id);

    target_system_id = config->GetInteger("dflogger", "target_system_id", target_system_id);
    target_component_id = config->GetInteger("dflogger", "target_component_id", target_component_id);

    return true;
}

bool DataFlash_Logger::make_new_log_filename(char *buffer, uint8_t bufferlen)
{
  uint8_t lastlog_buflen = 128;
  char lastlog_buf[128];
    // this was really beautiful, but I don't think SoloLink has an
    // RTC; it depends on GPS to update its clock (scribbled down
    // periodically?)

    // time_t t;

    // time(&t);
    // struct tm *timebits = gmtime(&t);

    // snprintf(buffer, bufferlen, "%s/%04d%02d%02d%02d%02d%02d.BIN",
    //          _log_directory_path,
    //          timebits->tm_year+1900,
    //          timebits->tm_mon+1,
    //          timebits->tm_mday,
    //          timebits->tm_hour,
    //          timebits->tm_min,
    //          timebits->tm_sec);


    memset(lastlog_buf, '\0', lastlog_buflen);
    snprintf(lastlog_buf, lastlog_buflen, "%s/LASTLOG.TXT", _log_directory_path);
{'fraction_non_alphanumeric': 0.12236640156271801, 'fraction_numerical': 0.01534812334310032, 'mean_word_length': 3.830188679245283, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7516645', 'n_tokens_mistral': 2691, 'n_tokens_neox': 2548, 'n_words': 501}