diff --git a/src/USB_Component.ttcn b/src/USB_Component.ttcn index de3d3ef..c38cba5 100644 --- a/src/USB_Component.ttcn +++ b/src/USB_Component.ttcn @@ -18,8 +18,12 @@ type record USB_Device_Match_vidpid { HEX4n vid, HEX4n pid }; +type record USB_Device_Match_path { + charstring path +}; type union USB_Device_Match { - USB_Device_Match_vidpid vid_pid + USB_Device_Match_vidpid vid_pid, + USB_Device_Match_path path }; function f_usb_init_vid_pid(HEX4n vendor_id, HEX4n product_id) runs on USB_CT { @@ -41,10 +45,35 @@ function f_usb_init_vid_pid(HEX4n vendor_id, HEX4n product_id) runs on USB_CT { g_USB_Tguard.stop; } +function f_usb_init_path(charstring path) runs on USB_CT { + map(self:USB, system:USB); + var USB_result res; + var integer req_hdl := f_usb_get_req_hdl(); + USB.send(ts_USB_open_path(path, device_hdl := g_dev_hdl, req_hdl := req_hdl)); + g_USB_Tguard.start; + alt { + [] USB.receive(tr_USB_result(req_hdl := req_hdl, device_hdl := g_dev_hdl)) -> value res { + log("Received ", res); + } + [] USB.receive { + testcase.stop("Couldn't open requested USB device"); + } + } + g_USB_Tguard.stop; +} + +private altstep as_Tguard() runs on USB_CT { +[] g_USB_Tguard.timeout { + testcase.stop("Timeout of global USB guard timer"); + } +} + function f_usb_init(USB_Device_Match udm) runs on USB_CT { activate(as_Tguard()); if (ischosen(udm.vid_pid)) { f_usb_init_vid_pid(udm.vid_pid.vid, udm.vid_pid.pid); + } else if (ischosen(udm.path)) { + f_usb_init_path(udm.path.path); } else { testcase.stop("Unsupported USB_Device_Match"); } diff --git a/src/USB_PT.cc b/src/USB_PT.cc index 689d234..d3ca740 100644 --- a/src/USB_PT.cc +++ b/src/USB_PT.cc @@ -343,6 +343,67 @@ void USB__PT_PROVIDER::outgoing_send(const USB__open__vid__pid& send_par) incoming_message(USB__result(send_par.req__hdl(), send_par.device__hdl(), rc)); } +static void stringify_usb_path(char *out, uint8_t bus_num, const uint8_t *ports, size_t num_ports) +{ + int length = 0; + int i; + + length += sprintf(out, "%u-%u", bus_num, ports[0]); + for (i = 1; i < num_ports; i++) + length += sprintf(out+length, ".%u", ports[i]); +} + +void USB__PT_PROVIDER::outgoing_send(const USB__open__path& send_par) +{ + unsigned int device_hdl = send_par.device__hdl(); + const CHARSTRING &in_path_char = send_par.path(); + const char *in_path = (const char *) in_path_char; + libusb_device_handle *dh = NULL; + libusb_device **list; + int rc, i; + + rc = libusb_get_device_list(mCtx, &list); + if (rc < 0) { + log("Error getting USB device list: %s\n", + libusb_strerror((enum libusb_error) rc)); + rc = -1; + goto out; + } + + for (i = 0; list[i] != NULL; i++) { + uint8_t ports[8]; + char path[256]; + libusb_device *dev = list[i]; + rc = libusb_get_port_numbers(dev, ports, sizeof(ports)); + stringify_usb_path(path, libusb_get_bus_number(dev), ports, rc); + log("Found USB Device at path %s", path); + if (!strcmp(in_path, path)) { + rc = libusb_open(dev, &dh); + if (rc < 0) { + log("Error opening USB device %s: %s", path, + libusb_strerror((enum libusb_error) rc)); + rc = -1; + } else { + USB_Device *udev = new USB_Device(this, dh, device_hdl); + mDevices.insert(std::make_pair(device_hdl, udev)); + log("Successfully opened USB device at path %s", path); + rc = 0; + } + break; + } + } + + if (!dh) { + log("No matching USB device for %s", in_path); + rc = -1; + } + libusb_free_device_list(list, 1); + +out: + incoming_message(USB__result(send_par.req__hdl(), send_par.device__hdl(), rc)); +} + + void USB__PT_PROVIDER::outgoing_send(const USB__set__configuration& send_par) { USB_Device *dev = usbdev_by_hdl(send_par.device__hdl()); diff --git a/src/USB_PT.hh b/src/USB_PT.hh index 41d00c7..6dbdb3e 100644 --- a/src/USB_PT.hh +++ b/src/USB_PT.hh @@ -94,6 +94,7 @@ protected: void user_stop(); void outgoing_send(const USB__open__vid__pid& send_par); + void outgoing_send(const USB__open__path& send_par); void outgoing_send(const USB__transfer& send_par); void outgoing_send(const USB__set__configuration& send_par); void outgoing_send(const USB__claim__interface& send_par); diff --git a/src/USB_PortType.ttcn b/src/USB_PortType.ttcn index cf2856b..735ec7d 100644 --- a/src/USB_PortType.ttcn +++ b/src/USB_PortType.ttcn @@ -3,6 +3,7 @@ import from USB_PortTypes all; type port USB_PT message { out USB_open_vid_pid; + out USB_open_path; out USB_set_configuration; out USB_claim_interface; out USB_release_interface; diff --git a/src/USB_PortTypes.ttcn b/src/USB_PortTypes.ttcn index 0d37ced..5e61943 100644 --- a/src/USB_PortTypes.ttcn +++ b/src/USB_PortTypes.ttcn @@ -60,6 +60,14 @@ module USB_PortTypes { }; /* Response: USB_result */ + type record USB_open_path { + integer req_hdl, + integer device_hdl, + charstring path + }; + /* Response: USB_result */ + + type record USB_set_configuration { integer req_hdl, integer device_hdl, @@ -132,6 +140,14 @@ ts_USB_open_vid_pid(USB_vendor_id vid, USB_product_id pid, integer device_hdl := product_id := pid } +template (value) USB_open_path +ts_USB_open_path(charstring path, integer device_hdl := -1, integer req_hdl := -1) := { + req_hdl := req_hdl, + device_hdl := device_hdl, + path := path +} + + template USB_result tr_USB_result(template integer req_hdl := ?, template integer device_hdl := ?, template integer result_code := ?) := { req_hdl := req_hdl,