Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rs usb api and implementations added #3828

Merged
merged 3 commits into from
May 16, 2019

Conversation

matkatz
Copy link
Contributor

@matkatz matkatz commented Apr 23, 2019

This PR creates a common USB API for the different operating systems.
As first step this API will be used for cross platform FW update API and tools.
In the future this infrastructure will allow single implementation for UVC/HID/TM2 for all the supported operating systems.

rsusb

DSO-10947

@matkatz matkatz requested review from ev-mp and dorodnic April 23, 2019 19:12
}

std::shared_ptr<usb_device> android_backend::create_usb_device(usb_device_info info) const {
throw std::runtime_error("create_usb_device Not supported");
std::shared_ptr<command_transfer> android_backend::create_usb_device(usb_device_info info) const {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method create_usb_device returns command_transfer ?
If so - please use "_dev" suffix as command_transfer is too vague
Also is this intended to work with non-Realsense devices, such as platform cam ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the original usb_device was an empty class which inherited command_transfer, since I removed usb_device I needed to replace it with command_transfer but I don't want to make more changes to the backend API in this PR unless it is necessary .

}

std::vector<usb_device_info> android_backend::query_usb_devices() const {
std::vector<usb_device_info> results;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls change the name to query_usb_devices_**info** for consistency

@@ -68,7 +80,7 @@ namespace librealsense {


std::shared_ptr<device_watcher> android_backend::create_device_watcher() const {
return std::make_shared<usb_host::device_watcher>();
return device_watcher_usbhost::instance();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be no need to wrap a singleton with shared_ptr.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to implement the backend API:
std::shared_ptr<device_watcher> create_device_watcher() const override;

uvc->vid = dev->get_info().vid;
uvc->pid = dev->get_info().pid;
usbhost_open(uvc.get(), mi);
return uvc;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function will open the first device with matched MI. How can one query the 2nd or 3rd device ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (device->deviceData.ctrl_if.bInterfaceNumber == mi) {
_device = device;
if (state == D0 && _power_state == D3) {
uint16_t vid = _info.vid, pid = _info.pid, mi = _info.mi;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vid/pid seem unused in this segment - pls recheck

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will remove

{
auto i = entry.second;
if(filter == USB_SUBCLASS_ANY ||
i->get_subclass() & filter ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put parentheses

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

function will be removed


virtual const usb_device_info get_info() const override { return _infos[0]; }
virtual const std::vector<usb_device_info> get_subdevices_infos() const override { return _infos; }
virtual const rs_usb_interface get_interface(uint8_t interface_number) const override { return _interfaces.at(interface_number); }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will throw if the index is not in the map

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_interface(uint8_t interface_number) will be removed, leaving only get_interfaces()

libusb_device_descriptor desc = { 0 };

auto rc = libusb_get_device_descriptor(lusb_device, &desc);
if (desc.idVendor != 0x8086)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For review - probably requires some sort of a mask - T265 , etc'
Log the devices that are filtered out

Copy link
Contributor Author

@matkatz matkatz May 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devices are filtered on context.cpp via pick__devices

I have also removed the 0x8086 filter

break;
}
}
libusb_free_device_list(list, 0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A common pattern in this and the next functions:
libusb_get_device_list
...
libusb_free_device_list

  • Needs a common RAII support

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will make RAII

class handle_libusb
{
public:
handle_libusb(libusb_device* device, uint8_t interface, int timeout_ms = 100) :
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment how this value was selected

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeout will be removed from the handle signature


}

bool usb_messenger_libusb::reset_endpoint(std::shared_ptr<usb_endpoint> endpoint)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be made const

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if(rv)
LOG_DEBUG("USB pipe " << ep << " reset successfully");
else
LOG_DEBUG("Failed to reset the USB pipe " << ep);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual result of the transfer is not registered (reduced to bool) will make it harder for debugging and maintenance

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usb status added to the log

Copy link
Collaborator

@ev-mp ev-mp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A huge transformation.
We'll need multiple things to review and polish.
The one thing - the class diagram should clearly depict the inheritance tree with all the interfaces and concrete classes. It is very hard to navigate otherwise


int usb_messenger_libusb::control_transfer(int request_type, int request, int value, int index, uint8_t* buffer, uint32_t length, uint32_t timeout_ms)
{
handle_libusb handle(_device->get_device(), index & 0xFF, timeout_ms);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please either perform a static_cast or add a note that the actual index is within 0-255.
You also need to check the input against things such as 0xabcd0011, which could be interpret as 0x11 without checking the higher bits

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the upper bytes are required for control transfer, the mask is extracting the interface number

return rv;
}

int usb_messenger_libusb::bulk_transfer(const std::shared_ptr<usb_endpoint>& endpoint, uint8_t* buffer, uint32_t length, uint32_t timeout_ms)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PLs make the in and out length param type identical (preferably int)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returned value replaced with usb status

@@ -66,35 +65,28 @@ namespace librealsense
return devices;
}

std::shared_ptr<usb_device> wmf_backend::create_usb_device(usb_device_info info) const
std::shared_ptr<command_transfer> wmf_backend::create_usb_device(usb_device_info info) const
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make the param const&

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to avoid changes to the backend API at this point

{
return try_record([&](recording* rec, lookup_key k)
{
auto dev = _source->create_usb_device(info);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing WS

@@ -1136,7 +1136,7 @@ namespace librealsense
return _rec->load_uvc_device_info_list();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation

for (auto&& entry : _interfaces)
{
auto i = entry.second;
if(filter == USB_SUBCLASS_ANY ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is multiplied several times (counted 3) - can it be refactored?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will be removed

virtual endpoint_type get_type() const override { return _type; }
virtual endpoint_direction get_direction() const override
{
return _address >= USB_ENDPOINT_DIRECTION_READ ?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is also C&P

return false;
for (auto&& guid : guids)
{
for (auto&& id : query_by_interface(guid, L"8086"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 8086 mask may not recognize T265

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will remove the filter


for (auto&& guid : guids)
{
for (auto&& id : query_by_interface(guid, L"8086"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


switch (devices.size())
{
case 0: printf("\nno USB device found\n\n"); break;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case will not be invoked - terminated on previous REQUIRE(devices.size());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

@ev-mp ev-mp merged commit f51b203 into IntelRealSense:development May 16, 2019
@matkatz matkatz deleted the rsusb-api branch July 9, 2019 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants