static int log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_log_push_cb push_cb, ambit_log_progress_cb progress_cb, void *userref) { int entries_read = 0; uint16_t log_entries_total = 0; uint16_t log_entries_walked = 0; uint16_t log_entries_notsynced = 0; ambit3_log_header_t log_header; ambit_log_entry_t *log_entry; libambit_sbem0102_data_t send_data_object, reply_data_object; LOG_INFO("Reading log headers"); log_header.header.activity_name = NULL; libambit_sbem0102_data_init(&send_data_object); libambit_sbem0102_data_init(&reply_data_object); libambit_sbem0102_data_add(&send_data_object, 0x8d, NULL, 0); if (libambit_sbem0102_command_request(&object->driver_data->sbem0102, ambit_command_ambit3_log_headers, &send_data_object, &reply_data_object) != 0) { LOG_WARNING("Failed to read log headers"); return -1; } if (object->driver_data->memory_maps.initialized == 0) { if (get_memory_maps(object) != 0) { return -1; } } // Initialize PMEM20 log before starting to read logs libambit_pmem20_log_init(&object->driver_data->pmem20, object->driver_data->memory_maps.excercise_log.start, object->driver_data->memory_maps.excercise_log.size); while (libambit_sbem0102_data_next(&reply_data_object) == 0) { switch (libambit_sbem0102_data_id(&reply_data_object)) { case 0x4e: log_entries_total = read16(libambit_sbem0102_data_ptr(&reply_data_object), 0); LOG_INFO("Number of logs=%d", log_entries_total); break; case 0x4f: log_entries_notsynced = read16(libambit_sbem0102_data_ptr(&reply_data_object), 0); LOG_INFO("Number of logs marked as not syncronized=%d", log_entries_notsynced); break; case 0x7e: if (parse_log_header(libambit_sbem0102_data_ptr(&reply_data_object), &log_header) == 0) { LOG_INFO("Log header parsed successfully"); if (skip_cb(userref, &log_header.header) != 0) { LOG_INFO("Reading data of log %d of %d", log_entries_walked + 1, log_entries_total); log_entry = libambit_pmem20_log_read_entry_address(&object->driver_data->pmem20, log_header.address, log_header.end_address - log_header.address); if (log_entry != NULL) { if (push_cb != NULL) { push_cb(userref, log_entry); } entries_read++; } } else { LOG_INFO("Log entry already exists, skipping"); } } else { LOG_INFO("Failed to parse log header"); } log_entries_walked++; if (progress_cb != NULL) { progress_cb(userref, log_entries_total, log_entries_walked, 100*log_entries_walked/log_entries_total); } break; default: break; } } libambit_sbem0102_data_free(&send_data_object); libambit_sbem0102_data_free(&reply_data_object); return entries_read; }
static int log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_log_push_cb push_cb, ambit_log_progress_cb progress_cb, void *userref) { int entries_read = 0; uint8_t *reply_data = NULL; size_t replylen = 0; uint16_t log_entries_total = 0; uint16_t log_entries_walked = 0; uint32_t more = 0x00000400; bool read_pmem = false; ambit_log_header_t log_header; ambit_log_entry_t *log_entry; LOG_INFO("Reading number of logs"); log_header.activity_name = NULL; /* * Read number of log entries */ if (libambit_protocol_command(object, ambit_command_log_count, NULL, 0, &reply_data, &replylen, 0) != 0) { LOG_WARNING("Failed to read number of log entries"); return -1; } log_entries_total = le16toh(*(uint16_t*)(reply_data + 2)); libambit_protocol_free(reply_data); LOG_INFO("Number of logs=%d", log_entries_total); /* * First part walks through headers to check if there is any point in start * reading the PMEM content. If no skip callback is defined, there is no * point in checking the headers, because no one can tell us to not include * the logs... */ if (skip_cb != NULL) { LOG_INFO("Look in headers for new logs"); // Rewind if (libambit_protocol_command(object, ambit_command_log_head_first, NULL, 0, &reply_data, &replylen, 0) != 0) { LOG_WARNING("Failed to rewind header pointer"); return -1; } more = le32toh(*(uint32_t*)reply_data); libambit_protocol_free(reply_data); // Loop through logs while more entries exists while (more == 0x00000400) { LOG_INFO("Reading next header"); // Go to next entry if (libambit_protocol_command(object, ambit_command_log_head_step, NULL, 0, &reply_data, &replylen, 0) != 0) { LOG_WARNING("Failed to walk to next header"); return -1; } libambit_protocol_free(reply_data); // Assume every header is composited by 2 parts, where only the // second is of interrest right now if (libambit_protocol_command(object, ambit_command_log_head, NULL, 0, &reply_data, &replylen, 0) != 0) { LOG_WARNING("Failed to read first part of header"); return -1; } libambit_protocol_free(reply_data); if (libambit_protocol_command(object, ambit_command_log_head, NULL, 0, &reply_data, &replylen, 0) == 0) { if (replylen > 8 && libambit_pmem20_log_parse_header(reply_data + 8, replylen - 8, &log_header) == 0) { if (skip_cb(userref, &log_header) != 0) { // Header was NOT skipped, break out! read_pmem = true; LOG_INFO("Found new entry, start reading log data"); break; } } else { LOG_ERROR("Failed to parse log header"); return -1; } libambit_protocol_free(reply_data); } else { LOG_WARNING("Failed to read second part of header"); return -1; } // Is there more entries to read? if (libambit_protocol_command(object, ambit_command_log_head_peek, NULL, 0, &reply_data, &replylen, 0) != 0) { LOG_WARNING("Failed to check for more headers"); return -1; } more = le32toh(*(uint32_t*)reply_data); libambit_protocol_free(reply_data); } } else { LOG_INFO("No skip callback defined, reading log data"); read_pmem = true; } if (read_pmem) { if (libambit_pmem20_log_init(&object->driver_data->pmem20, PMEM20_LOG_START, PMEM20_LOG_SIZE) != 0) { return -1; } // Loop through all log entries, first check headers while (log_entries_walked < log_entries_total && libambit_pmem20_log_next_header(&object->driver_data->pmem20, &log_header) == 1) { LOG_INFO("Reading header of log %d of %d", log_entries_walked + 1, log_entries_total); if (progress_cb != NULL) { progress_cb(userref, log_entries_total, log_entries_walked+1, 100*log_entries_walked/log_entries_total); } // Check if this entry needs to be read if (skip_cb == NULL || skip_cb(userref, &log_header) != 0) { LOG_INFO("Reading data of log %d of %d", log_entries_walked + 1, log_entries_total); log_entry = libambit_pmem20_log_read_entry(&object->driver_data->pmem20); if (log_entry != NULL) { if (push_cb != NULL) { push_cb(userref, log_entry); } entries_read++; } } else { LOG_INFO("Log %d of %d already exists, skip reading data", log_entries_walked + 1, log_entries_total); } log_entries_walked++; if (progress_cb != NULL) { progress_cb(userref, log_entries_total, log_entries_walked, 100*log_entries_walked/log_entries_total); } } } LOG_INFO("%d entries read", entries_read); return entries_read; }