sanei_usb: Add support for record testing mode

merge-requests/92/head
Povilas Kanapickas 2019-04-27 12:16:13 +03:00
rodzic 7de8efd395
commit b30406873c
3 zmienionych plików z 118 dodań i 20 usunięć

Wyświetl plik

@ -1180,7 +1180,7 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
dev_name = strchr (full_name, ':');
int is_fakeusb = 0, is_fakeusbdev = 0;
int is_fakeusb = 0, is_fakeusbdev = 0, is_fakeusbout = 0;
if (dev_name)
{
@ -1188,6 +1188,8 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
dev_name - full_name == 7;
is_fakeusbdev = strncmp(full_name, "fakeusbdev", dev_name - full_name) == 0 &&
dev_name - full_name == 10;
is_fakeusbout = strncmp(full_name, "fakeusbout", dev_name - full_name) == 0 &&
dev_name - full_name == 10;
}
if (is_fakeusb || is_fakeusbdev)
@ -1204,18 +1206,46 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
return SANE_STATUS_ACCESS_DENIED;
}
}
else if (dev_name)
{
be_name = strndup(full_name, dev_name - full_name);
++dev_name; /* skip colon */
}
else
{
/* if no colon interpret full_name as the backend name; an empty
backend device name will cause us to open the first device of
that backend. */
be_name = strdup(full_name);
dev_name = "";
char* fakeusbout_path = NULL;
if (is_fakeusbout)
{
++dev_name; // skip colon
const char* path_end = strchr(dev_name, ':');
if (path_end == NULL)
{
DBG (0, "%s: the device name does not contain path\n", __func__);
return SANE_STATUS_INVAL;
}
fakeusbout_path = strndup(dev_name, path_end - dev_name);
full_name = path_end + 1; // skip colon
dev_name = strchr(full_name, ':');
}
if (dev_name)
{
be_name = strndup(full_name, dev_name - full_name);
++dev_name; /* skip colon */
}
else
{
/* if no colon interpret full_name as the backend name; an empty
backend device name will cause us to open the first device of
that backend. */
be_name = strdup(full_name);
dev_name = "";
}
if (is_fakeusbout)
{
status = sanei_usb_testing_enable_record(fakeusbout_path, be_name);
free(fakeusbout_path);
if (status != SANE_STATUS_GOOD)
return status;
}
}
if (!be_name)

Wyświetl plik

@ -205,10 +205,12 @@ extern SANE_Status sanei_usb_testing_enable_replay(SANE_String_Const path,
*
* Initializes sanei_usb for recording communication with the scanner. This
* function must be called before sanei_usb_init().
*
* @param path Path to the XML data file.
*
* @param path Path to the XML data file.
* @param be_name The name of the backend to enable recording for.
*/
extern SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path);
extern SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path,
SANE_String_Const be_name);
/** Returns backend name for testing.
*

Wyświetl plik

@ -193,6 +193,7 @@ static sanei_usb_testing_mode testing_mode = sanei_usb_testing_mode_disabled;
static int testing_development_mode = 0;
int testing_known_commands_input_failed = 0;
unsigned testing_last_known_seq = 0;
SANE_String testing_record_backend = NULL;
xmlNode* testing_append_commands_node = NULL;
// XML file from which we read testing data
@ -516,10 +517,13 @@ void fail_test()
{
}
SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path)
SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path, SANE_String_Const be_name)
{
(void) path;
return SANE_STATUS_UNSUPPORTED;
testing_mode = sanei_usb_testing_mode_record;
testing_record_backend = strdup(be_name);
testing_xml_path = strdup(path);
return SANE_STATUS_GOOD;
}
static xmlNode* sanei_xml_find_first_child_with_name(xmlNode* parent,
@ -985,7 +989,8 @@ static SANE_Status sanei_usb_testing_init()
if (testing_mode == sanei_usb_testing_mode_record)
{
return SANE_STATUS_UNSUPPORTED;
testing_xml_doc = xmlNewDoc((const xmlChar*)"1.0");
return SANE_STATUS_GOOD;
}
if (device_number != 0)
@ -1137,8 +1142,13 @@ static SANE_Status sanei_usb_testing_init()
static void sanei_usb_testing_exit()
{
if (testing_development_mode)
if (testing_development_mode || testing_mode == sanei_usb_testing_mode_record)
{
if (testing_mode == sanei_usb_testing_mode_record)
{
xmlAddNextSibling(testing_append_commands_node, xmlNewText((const xmlChar*)"\n "));
free(testing_record_backend);
}
xmlSaveFileEnc(testing_xml_path, testing_xml_doc, "UTF-8");
}
xmlFreeDoc(testing_xml_doc);
@ -2087,6 +2097,62 @@ sanei_usb_get_endpoint (SANE_Int dn, SANE_Int ep_type)
}
}
static void sanei_usb_record_open(SANE_Int dn)
{
xmlNode* e_root = xmlNewNode(NULL, (const xmlChar*) "device_capture");
xmlDocSetRootElement(testing_xml_doc, e_root);
xmlNewProp(e_root, (const xmlChar*)"backend", (const xmlChar*) testing_record_backend);
xmlNode* e_description = xmlNewChild(e_root, NULL, (const xmlChar*) "description", NULL);
sanei_xml_set_hex_attr(e_description, "id_vendor", devices[dn].vendor);
sanei_xml_set_hex_attr(e_description, "id_product", devices[dn].product);
xmlNode* e_configurations = xmlNewChild(e_description, NULL,
(const xmlChar*) "configurations", NULL);
xmlNode* e_configuration = xmlNewChild(e_configurations, NULL,
(const xmlChar*) "configuration", NULL);
sanei_xml_set_uint_attr(e_configuration, "number", 1);
xmlNode* e_interface = xmlNewChild(e_configuration, NULL, (const xmlChar*) "interface", NULL);
sanei_xml_set_uint_attr(e_interface, "number", devices[dn].interface_nr);
struct endpoint_data_desc {
const char* transfer_type;
const char* direction;
SANE_Int ep_address;
};
struct endpoint_data_desc endpoints[8] =
{
{ "BULK", "IN", devices[dn].bulk_in_ep },
{ "BULK", "OUT", devices[dn].bulk_out_ep },
{ "ISOCHRONOUS", "IN", devices[dn].iso_in_ep },
{ "ISOCHRONOUS", "OUT", devices[dn].iso_out_ep },
{ "INTERRUPT", "IN", devices[dn].int_in_ep },
{ "INTERRUPT", "OUT", devices[dn].int_out_ep },
{ "CONTROL", "IN", devices[dn].control_in_ep },
{ "CONTROL", "OUT", devices[dn].control_out_ep }
};
for (int i = 0; i < 8; ++i)
{
if (endpoints[i].ep_address)
{
xmlNode* e_endpoint = xmlNewChild(e_interface, NULL, (const xmlChar*)"endpoint", NULL);
xmlNewProp(e_endpoint, (const xmlChar*)"transfer_type",
(const xmlChar*) endpoints[i].transfer_type);
sanei_xml_set_uint_attr(e_endpoint, "number", endpoints[i].ep_address & 0x0f);
xmlNewProp(e_endpoint, (const xmlChar*)"direction",
(const xmlChar*) endpoints[i].direction);
sanei_xml_set_hex_attr(e_endpoint, "address", endpoints[i].ep_address);
}
}
xmlNode* e_transactions = xmlNewChild(e_root, NULL, (const xmlChar*)"transactions", NULL);
// add an empty node so that we have something to append to
testing_append_commands_node = xmlAddChild(e_transactions, xmlNewText((const xmlChar*)""));;
}
SANE_Status
sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)
{
@ -2645,7 +2711,7 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)
if (testing_mode == sanei_usb_testing_mode_record)
{
// ZZTODO: record the USB state
sanei_usb_record_open(devcount);
}
devices[devcount].open = SANE_TRUE;