genesys: Add a way to record debug messages to USB captures

merge-requests/95/head
Povilas Kanapickas 2019-06-28 18:18:28 +03:00
rodzic 1be824f2c5
commit aa6bdba74d
5 zmienionych plików z 157 dodań i 16 usunięć

Wyświetl plik

@ -487,12 +487,12 @@ libgenesys_la_SOURCES = genesys.cc genesys.h genesys_sanei.h genesys_sanei.cc ge
genesys_gl847.cc genesys_gl847.h genesys_gl124.cc genesys_gl124.h \
genesys_low.cc genesys_low.h
libgenesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys
libgenesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys $(XML_CFLAGS)
nodist_libsane_genesys_la_SOURCES = genesys-s.cc
libsane_genesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys
libsane_genesys_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS)
libsane_genesys_la_LIBADD = $(COMMON_LIBS) libgenesys.la ../sanei/sanei_magic.lo ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo $(MATH_LIB) $(USB_LIBS) $(RESMGR_LIBS)
libsane_genesys_la_LIBADD = $(COMMON_LIBS) libgenesys.la ../sanei/sanei_magic.lo ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo $(MATH_LIB) $(USB_LIBS) $(XML_LIBS) $(RESMGR_LIBS)
EXTRA_DIST += genesys.conf.in
# TODO: Why are this distributed but not compiled?
EXTRA_DIST += genesys_conv.cc genesys_conv_hlp.cc genesys_devices.cc

Wyświetl plik

@ -45,6 +45,10 @@
#include "genesys_sanei.h"
#if WITH_USB_RECORD_REPLAY
#include <libxml/tree.h>
#endif
UsbDevice::~UsbDevice()
{
if (is_open()) {
@ -138,3 +142,131 @@ void UsbDevice::set_not_open()
is_open_ = false;
name_ = "";
}
extern "C" {
typedef enum {
sanei_usb_testing_mode_disabled = 0,
sanei_usb_testing_mode_record,
sanei_usb_testing_mode_replay,
}
sanei_usb_testing_mode;
extern sanei_usb_testing_mode testing_mode;
} // extern "C"
#if WITH_USB_RECORD_REPLAY
// from sanei_usb.c
#define FAIL_TEST(func, ...) \
do { \
DBG(1, "%s: FAIL: ", func); \
DBG(1, __VA_ARGS__); \
fail_test(); \
} while (0)
#define FAIL_TEST_TX(func, node, ...) \
do { \
sanei_xml_print_seq_if_any(node, func); \
DBG(1, "%s: FAIL: ", func); \
DBG(1, __VA_ARGS__); \
fail_test(); \
} while (0)
extern "C" {
void fail_test();
xmlNode* sanei_xml_get_next_tx_node();
int sanei_xml_is_known_commands_end(xmlNode* node);
void sanei_xml_print_seq_if_any(xmlNode* node, const char* parent_fun);
void sanei_xml_set_uint_attr(xmlNode* node, const char* attr_name,
unsigned attr_value);
xmlNode* sanei_xml_append_command(xmlNode* sibling,
int indent, xmlNode* e_command);
void sanei_xml_record_seq(xmlNode* node);
void sanei_xml_break_if_needed(xmlNode* node);
int sanei_usb_check_attr(xmlNode* node, const char* attr_name,
const char* expected, const char* parent_fun);
extern xmlNode* testing_append_commands_node;
extern unsigned testing_last_known_seq;
extern int testing_development_mode;
extern int testing_known_commands_input_failed;
} // extern "C"
static void sanei_usb_record_debug_msg(xmlNode* node, SANE_String_Const message)
{
int node_was_null = node == NULL;
if (node_was_null)
node = testing_append_commands_node;
xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"debug");
sanei_xml_set_uint_attr(e_tx, "seq", ++testing_last_known_seq);
xmlNewProp(e_tx, (const xmlChar*)"message", (const xmlChar*)message);
node = sanei_xml_append_command(node, node_was_null, e_tx);
if (node_was_null)
testing_append_commands_node = node;
}
static void sanei_usb_record_replace_debug_msg(xmlNode* node, SANE_String_Const message)
{
if (!testing_development_mode)
return;
testing_last_known_seq--;
sanei_usb_record_debug_msg(node, message);
xmlUnlinkNode(node);
xmlFreeNode(node);
}
static void sanei_usb_replay_debug_msg(SANE_String_Const message)
{
if (testing_known_commands_input_failed)
return;
xmlNode* node = sanei_xml_get_next_tx_node();
if (node == NULL)
{
FAIL_TEST(__func__, "no more transactions\n");
return;
}
if (sanei_xml_is_known_commands_end(node))
{
sanei_usb_record_debug_msg(NULL, message);
return;
}
sanei_xml_record_seq(node);
sanei_xml_break_if_needed(node);
if (xmlStrcmp(node->name, (const xmlChar*)"debug") != 0)
{
FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n",
(const char*) node->name);
sanei_usb_record_replace_debug_msg(node, message);
}
if (!sanei_usb_check_attr(node, "message", message, __func__))
{
sanei_usb_record_replace_debug_msg(node, message);
}
}
void sanei_usb_testing_record_message(SANE_String_Const message)
{
if (testing_mode == sanei_usb_testing_mode_record)
{
sanei_usb_record_debug_msg(NULL, message);
}
if (testing_mode == sanei_usb_testing_mode_replay)
{
sanei_usb_replay_debug_msg(message);
}
}
#else
void sanei_usb_testing_record_message(SANE_String_Const message)
{
(void) message;
}
#endif

Wyświetl plik

@ -94,4 +94,6 @@ private:
int device_num_ = 0;
};
void sanei_usb_testing_record_message(SANE_String_Const message);
#endif // BACKEND_GENESYS_SANEI_H

Wyświetl plik

@ -224,6 +224,13 @@ extern SANE_String sanei_usb_testing_get_backend();
*/
extern SANE_Bool sanei_usb_is_replay_mode_enabled();
/** Records a debug message in the captured USB data if testing mode is enabled. If testing mode
* is not enabled, this function does nothing.
*
* @param msg Message to record
*/
extern void sanei_usb_testing_record_message(SANE_String_Const message);
/** Initialize sanei_usb.
*
* Call this before any other sanei_usb function.

Wyświetl plik

@ -191,10 +191,10 @@ typedef enum
sanei_usb_testing_mode;
// Whether testing mode has been enabled
static sanei_usb_testing_mode testing_mode = sanei_usb_testing_mode_disabled;
sanei_usb_testing_mode testing_mode = sanei_usb_testing_mode_disabled;
#if WITH_USB_RECORD_REPLAY
static int testing_development_mode = 0;
int testing_development_mode = 0;
int testing_known_commands_input_failed = 0;
unsigned testing_last_known_seq = 0;
SANE_String testing_record_backend = NULL;
@ -577,7 +577,7 @@ static int sanei_xml_get_prop_uint(xmlNode* node, const char* name)
return attr_uint;
}
static void sanei_xml_print_seq_if_any(xmlNode* node, const char* parent_fun)
void sanei_xml_print_seq_if_any(xmlNode* node, const char* parent_fun)
{
char* attr = sanei_xml_get_prop(node, "seq");
if (attr == NULL)
@ -627,7 +627,7 @@ static int sanei_xml_is_transaction_ignored(xmlNode* node)
static xmlNode* sanei_xml_skip_non_tx_nodes(xmlNode* node)
{
const char* known_node_names[] = {
"control_tx", "bulk_tx", "interrupt_tx", "known_commands_end"
"control_tx", "bulk_tx", "interrupt_tx", "debug", "known_commands_end"
};
while (node != NULL)
@ -653,7 +653,7 @@ static xmlNode* sanei_xml_skip_non_tx_nodes(xmlNode* node)
return node;
}
static int sanei_xml_is_known_commands_end(xmlNode* node)
int sanei_xml_is_known_commands_end(xmlNode* node)
{
if (!testing_development_mode || node == NULL)
return 0;
@ -667,7 +667,7 @@ static xmlNode* sanei_xml_peek_next_tx_node()
}
// returns next transaction node that is not get_descriptor
static xmlNode* sanei_xml_get_next_tx_node()
xmlNode* sanei_xml_get_next_tx_node()
{
xmlNode* next = testing_xml_next_tx_node;
@ -802,8 +802,8 @@ static void sanei_xml_set_hex_attr(xmlNode* node, const char* attr_name,
xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf);
}
static void sanei_xml_set_uint_attr(xmlNode* node, const char* attr_name,
unsigned attr_value)
void sanei_xml_set_uint_attr(xmlNode* node, const char* attr_name,
unsigned attr_value)
{
const int buf_size = 128;
char buf[buf_size];
@ -811,8 +811,8 @@ static void sanei_xml_set_uint_attr(xmlNode* node, const char* attr_name,
xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf);
}
static xmlNode* sanei_xml_append_command(xmlNode* sibling,
int indent, xmlNode* e_command)
xmlNode* sanei_xml_append_command(xmlNode* sibling,
int indent, xmlNode* e_command)
{
if (indent)
{
@ -831,7 +831,7 @@ static void sanei_xml_command_common_props(xmlNode* node, int endpoint_number,
xmlNewProp(node, (const xmlChar*)"direction", (const xmlChar*)direction);
}
static void sanei_xml_record_seq(xmlNode* node)
void sanei_xml_record_seq(xmlNode* node)
{
int seq = sanei_xml_get_prop_uint(node, "seq");
if (seq > 0)
@ -842,7 +842,7 @@ static void sanei_xml_break()
{
}
static void sanei_xml_break_if_needed(xmlNode* node)
void sanei_xml_break_if_needed(xmlNode* node)
{
char* attr = sanei_xml_get_prop(node, "debug_break");
if (attr != NULL)
@ -853,8 +853,8 @@ static void sanei_xml_break_if_needed(xmlNode* node)
}
// returns 1 on success
static int sanei_usb_check_attr(xmlNode* node, const char* attr_name,
const char* expected, const char* parent_fun)
int sanei_usb_check_attr(xmlNode* node, const char* attr_name,
const char* expected, const char* parent_fun)
{
char* attr = sanei_xml_get_prop(node, attr_name);
if (attr == NULL)