kopia lustrzana https://gitlab.com/sane-project/backends
genesys: Add a way to record debug messages to USB captures
rodzic
1be824f2c5
commit
aa6bdba74d
|
@ -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_gl847.cc genesys_gl847.h genesys_gl124.cc genesys_gl124.h \
|
||||||
genesys_low.cc genesys_low.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
|
nodist_libsane_genesys_la_SOURCES = genesys-s.cc
|
||||||
libsane_genesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys
|
libsane_genesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys
|
||||||
libsane_genesys_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS)
|
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
|
EXTRA_DIST += genesys.conf.in
|
||||||
# TODO: Why are this distributed but not compiled?
|
# TODO: Why are this distributed but not compiled?
|
||||||
EXTRA_DIST += genesys_conv.cc genesys_conv_hlp.cc genesys_devices.cc
|
EXTRA_DIST += genesys_conv.cc genesys_conv_hlp.cc genesys_devices.cc
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
|
|
||||||
#include "genesys_sanei.h"
|
#include "genesys_sanei.h"
|
||||||
|
|
||||||
|
#if WITH_USB_RECORD_REPLAY
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
UsbDevice::~UsbDevice()
|
UsbDevice::~UsbDevice()
|
||||||
{
|
{
|
||||||
if (is_open()) {
|
if (is_open()) {
|
||||||
|
@ -138,3 +142,131 @@ void UsbDevice::set_not_open()
|
||||||
is_open_ = false;
|
is_open_ = false;
|
||||||
name_ = "";
|
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
|
||||||
|
|
|
@ -94,4 +94,6 @@ private:
|
||||||
int device_num_ = 0;
|
int device_num_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void sanei_usb_testing_record_message(SANE_String_Const message);
|
||||||
|
|
||||||
#endif // BACKEND_GENESYS_SANEI_H
|
#endif // BACKEND_GENESYS_SANEI_H
|
||||||
|
|
|
@ -224,6 +224,13 @@ extern SANE_String sanei_usb_testing_get_backend();
|
||||||
*/
|
*/
|
||||||
extern SANE_Bool sanei_usb_is_replay_mode_enabled();
|
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.
|
/** Initialize sanei_usb.
|
||||||
*
|
*
|
||||||
* Call this before any other sanei_usb function.
|
* Call this before any other sanei_usb function.
|
||||||
|
|
|
@ -191,10 +191,10 @@ typedef enum
|
||||||
sanei_usb_testing_mode;
|
sanei_usb_testing_mode;
|
||||||
|
|
||||||
// Whether testing mode has been enabled
|
// 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
|
#if WITH_USB_RECORD_REPLAY
|
||||||
static int testing_development_mode = 0;
|
int testing_development_mode = 0;
|
||||||
int testing_known_commands_input_failed = 0;
|
int testing_known_commands_input_failed = 0;
|
||||||
unsigned testing_last_known_seq = 0;
|
unsigned testing_last_known_seq = 0;
|
||||||
SANE_String testing_record_backend = NULL;
|
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;
|
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");
|
char* attr = sanei_xml_get_prop(node, "seq");
|
||||||
if (attr == NULL)
|
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)
|
static xmlNode* sanei_xml_skip_non_tx_nodes(xmlNode* node)
|
||||||
{
|
{
|
||||||
const char* known_node_names[] = {
|
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)
|
while (node != NULL)
|
||||||
|
@ -653,7 +653,7 @@ static xmlNode* sanei_xml_skip_non_tx_nodes(xmlNode* node)
|
||||||
return 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)
|
if (!testing_development_mode || node == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -667,7 +667,7 @@ static xmlNode* sanei_xml_peek_next_tx_node()
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns next transaction node that is not get_descriptor
|
// 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;
|
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);
|
xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sanei_xml_set_uint_attr(xmlNode* node, const char* attr_name,
|
void sanei_xml_set_uint_attr(xmlNode* node, const char* attr_name,
|
||||||
unsigned attr_value)
|
unsigned attr_value)
|
||||||
{
|
{
|
||||||
const int buf_size = 128;
|
const int buf_size = 128;
|
||||||
char buf[buf_size];
|
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);
|
xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static xmlNode* sanei_xml_append_command(xmlNode* sibling,
|
xmlNode* sanei_xml_append_command(xmlNode* sibling,
|
||||||
int indent, xmlNode* e_command)
|
int indent, xmlNode* e_command)
|
||||||
{
|
{
|
||||||
if (indent)
|
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);
|
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");
|
int seq = sanei_xml_get_prop_uint(node, "seq");
|
||||||
if (seq > 0)
|
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");
|
char* attr = sanei_xml_get_prop(node, "debug_break");
|
||||||
if (attr != NULL)
|
if (attr != NULL)
|
||||||
|
@ -853,8 +853,8 @@ static void sanei_xml_break_if_needed(xmlNode* node)
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns 1 on success
|
// returns 1 on success
|
||||||
static int sanei_usb_check_attr(xmlNode* node, const char* attr_name,
|
int sanei_usb_check_attr(xmlNode* node, const char* attr_name,
|
||||||
const char* expected, const char* parent_fun)
|
const char* expected, const char* parent_fun)
|
||||||
{
|
{
|
||||||
char* attr = sanei_xml_get_prop(node, attr_name);
|
char* attr = sanei_xml_get_prop(node, attr_name);
|
||||||
if (attr == NULL)
|
if (attr == NULL)
|
||||||
|
|
Ładowanie…
Reference in New Issue