diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b645e7a..9f97c79 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -43,4 +43,10 @@ add_example(boot_firmware boot_firmware.cpp) add_example(xlink_server xlink_server.cpp) # Server example -add_example(xlink_server2 xlink_server2.cpp) \ No newline at end of file +add_example(xlink_server2 xlink_server2.cpp) + +# Server example +add_example(xlink_usb_server xlink_usb_server.cpp) + +# Client example +add_example(xlink_usb_client xlink_usb_client.cpp) diff --git a/examples/xlink_usb_client.cpp b/examples/xlink_usb_client.cpp new file mode 100644 index 0000000..f46656c --- /dev/null +++ b/examples/xlink_usb_client.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "XLink/XLink.h" +#include "XLink/XLinkPublicDefines.h" +#include "XLink/XLinkLog.h" + +// Common constants +const uint8_t DUMMY_DATA[1024*128] = {}; +XLinkGlobalHandler_t xlinkGlobalHandler = {}; + +// Client +int main(int argc, char** argv) { + if (argc != 2) { + printf("Usage: xlink_usb_client [name of device]\n"); + exit(1); + } + + XLinkGlobalHandler_t gHandler; + XLinkInitialize(&gHandler); + + mvLogDefaultLevelSet(MVLOG_ERROR); + + deviceDesc_t deviceDesc; + strcpy(deviceDesc.name, argv[1]); + deviceDesc.protocol = X_LINK_USB_VSC; + // deviceDesc.protocol = X_LINK_USB_EP; + + printf("Device name: %s\n", deviceDesc.name); + + XLinkHandler_t handler; + handler.devicePath = deviceDesc.name; + handler.protocol = deviceDesc.protocol; + auto connRet = XLinkConnect(&handler); + printf("Connection returned: %s\n", XLinkErrorToStr(connRet)); + + if(connRet != X_LINK_SUCCESS) { + return -1; + } + + auto s = XLinkOpenStream(handler.linkId, "test_0", sizeof(DUMMY_DATA)); + if(s == INVALID_STREAM_ID){ + printf("Open stream failed...\n"); + } else { + printf("Open stream OK - id: 0x%08X\n", s); + } + + streamPacketDesc_t p; + auto r = XLinkReadMoveData(s, &p); + if (r == X_LINK_SUCCESS) { + printf("Read successful: 0x%08X\n", r); + } else { + printf("Read failed...\n"); + } + XLinkDeallocateMoveData(p.data, p.length); + + auto w = XLinkWriteData(s, (uint8_t*) &s, sizeof(s)); + if (w == X_LINK_SUCCESS) { + printf("Write successful: 0x%08X\n", w); + } else { + printf("Write failed...\n"); + } + + return 0; +} diff --git a/examples/xlink_usb_server.cpp b/examples/xlink_usb_server.cpp new file mode 100644 index 0000000..db0a0d3 --- /dev/null +++ b/examples/xlink_usb_server.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "XLink/XLink.h" +#include "XLink/XLinkPublicDefines.h" +#include "XLink/XLinkLog.h" + +// Common constants +const uint8_t DUMMY_DATA[1024*128] = {}; +XLinkGlobalHandler_t xlinkGlobalHandler = {}; + +// Server +int main(int argc, const char** argv){ + xlinkGlobalHandler.protocol = X_LINK_USB_EP; + + // Initialize and suppress XLink logs + mvLogDefaultLevelSet(MVLOG_ERROR); + auto status = XLinkInitialize(&xlinkGlobalHandler); + if(X_LINK_SUCCESS != status) { + throw std::runtime_error("Couldn't initialize XLink"); + } + + XLinkHandler_t handler; + // Write is ep1, read is ep2 + handler.devicePath = "/dev/usb-ffs/depthai_device/ep1"; + handler.devicePath2 = "/dev/usb-ffs/depthai_device/ep2"; + handler.protocol = X_LINK_USB_EP; + auto serverRet = XLinkServer(&handler, "eps", X_LINK_BOOTED, X_LINK_MYRIAD_X); + printf("Connection returned: %s\n", XLinkErrorToStr(serverRet)); + + // loop through streams + auto s = XLinkOpenStream(0, "test_0", sizeof(DUMMY_DATA)); + if(s == INVALID_STREAM_ID){ + printf("Open stream failed...\n"); + } else { + printf("Open stream OK - id: 0x%08X\n", s); + } + + auto w = XLinkWriteData(s, (uint8_t*) &s, sizeof(s)); + if (w == X_LINK_SUCCESS) { + printf("Write successful: 0x%08X\n", w); + } else { + printf("Write failed...\n"); + } + + // Wait to make sure we caugth up to all requests + std::this_thread::sleep_for(std::chrono::seconds(2)); + + return 0; +} diff --git a/include/XLink/XLinkPublicDefines.h b/include/XLink/XLinkPublicDefines.h index 69545c1..f665813 100644 --- a/include/XLink/XLinkPublicDefines.h +++ b/include/XLink/XLinkPublicDefines.h @@ -62,6 +62,7 @@ typedef enum{ X_LINK_PCIE, X_LINK_IPC, X_LINK_TCP_IP, + X_LINK_USB_EP, X_LINK_NMB_OF_PROTOCOLS, X_LINK_ANY_PROTOCOL } XLinkProtocol_t; diff --git a/src/pc/PlatformData.c b/src/pc/PlatformData.c index 874c2ae..557d965 100644 --- a/src/pc/PlatformData.c +++ b/src/pc/PlatformData.c @@ -57,6 +57,8 @@ extern int usbFdWrite; extern int usbFdRead; #endif /*USE_USB_VSC*/ +#include "usb_host_ep.h" + // ------------------------------------ // Wrappers declaration. Begin. // ------------------------------------ @@ -79,7 +81,7 @@ int XLinkPlatformWrite(xLinkDeviceHandle_t *deviceHandle, void *data, int size) if(!XLinkIsProtocolInitialized(deviceHandle->protocol)) { return X_LINK_PLATFORM_DRIVER_NOT_LOADED+deviceHandle->protocol; } - + switch (deviceHandle->protocol) { case X_LINK_USB_VSC: case X_LINK_USB_CDC: @@ -91,6 +93,9 @@ int XLinkPlatformWrite(xLinkDeviceHandle_t *deviceHandle, void *data, int size) case X_LINK_TCP_IP: return tcpipPlatformWrite(deviceHandle->xLinkFD, data, size); + case X_LINK_USB_EP: + return usbEpPlatformWrite(deviceHandle->xLinkFD, data, size); + default: return X_LINK_PLATFORM_INVALID_PARAMETERS; } @@ -113,6 +118,9 @@ int XLinkPlatformRead(xLinkDeviceHandle_t *deviceHandle, void *data, int size) case X_LINK_TCP_IP: return tcpipPlatformRead(deviceHandle->xLinkFD, data, size); + case X_LINK_USB_EP: + return usbEpPlatformRead(deviceHandle->xLinkFD, data, size); + default: return X_LINK_PLATFORM_INVALID_PARAMETERS; } diff --git a/src/pc/PlatformDeviceControl.c b/src/pc/PlatformDeviceControl.c index 855edc9..a6fbc77 100644 --- a/src/pc/PlatformDeviceControl.c +++ b/src/pc/PlatformDeviceControl.c @@ -8,6 +8,7 @@ #include "XLinkPlatform.h" #include "XLinkPlatformErrorUtils.h" #include "usb_host.h" +#include "usb_host_ep.h" #include "pcie_host.h" #include "tcpip_host.h" #include "XLinkStringUtils.h" @@ -82,17 +83,22 @@ xLinkPlatformErrorCode_t XLinkPlatformInit(XLinkGlobalHandler_t* globalHandler) { // Set that all protocols are initialized at first for(int i = 0; i < X_LINK_NMB_OF_PROTOCOLS; i++) { - xlinkSetProtocolInitialized(i, 1); + xlinkSetProtocolInitialized(i, 1); } // check for failed initialization; LIBUSB_SUCCESS = 0 if (usbInitialize(globalHandler->options) != 0) { - xlinkSetProtocolInitialized(X_LINK_USB_VSC, 0); + xlinkSetProtocolInitialized(X_LINK_USB_VSC, 0); + } + + // Initialize the USB EPs if present + if(usbEpInitialize() != 0) { + xlinkSetProtocolInitialized(X_LINK_USB_EP, 0); } // Initialize tcpip protocol if necessary if(tcpip_initialize() != TCPIP_HOST_SUCCESS) { - xlinkSetProtocolInitialized(X_LINK_TCP_IP, 0); + xlinkSetProtocolInitialized(X_LINK_TCP_IP, 0); } return X_LINK_PLATFORM_SUCCESS; @@ -170,6 +176,7 @@ xLinkPlatformErrorCode_t XLinkPlatformConnect(const char* devPathRead, const cha if(!XLinkIsProtocolInitialized(protocol)) { return X_LINK_PLATFORM_DRIVER_NOT_LOADED+protocol; } + switch (protocol) { case X_LINK_USB_VSC: case X_LINK_USB_CDC: @@ -181,6 +188,9 @@ xLinkPlatformErrorCode_t XLinkPlatformConnect(const char* devPathRead, const cha case X_LINK_TCP_IP: return tcpipPlatformConnect(devPathRead, devPathWrite, fd); + case X_LINK_USB_EP: + return usbEpPlatformConnect(devPathRead, devPathWrite, fd); + default: return X_LINK_PLATFORM_INVALID_PARAMETERS; } @@ -192,6 +202,9 @@ xLinkPlatformErrorCode_t XLinkPlatformServer(const char* devPathRead, const char case X_LINK_TCP_IP: return tcpipPlatformServer(devPathRead, devPathWrite, fd); + case X_LINK_USB_EP: + return usbEpPlatformServer(devPathRead, devPathWrite, fd); + default: return X_LINK_PLATFORM_INVALID_PARAMETERS; } @@ -239,6 +252,9 @@ xLinkPlatformErrorCode_t XLinkPlatformCloseRemote(xLinkDeviceHandle_t* deviceHan case X_LINK_TCP_IP: return tcpipPlatformClose(deviceHandle->xLinkFD); + + case X_LINK_USB_EP: + return usbEpPlatformClose(deviceHandle->xLinkFD); default: return X_LINK_PLATFORM_INVALID_PARAMETERS; diff --git a/src/pc/protocols/usb_host.cpp b/src/pc/protocols/usb_host.cpp index d4174db..167c757 100644 --- a/src/pc/protocols/usb_host.cpp +++ b/src/pc/protocols/usb_host.cpp @@ -237,6 +237,7 @@ extern "C" xLinkPlatformErrorCode_t refLibusbDeviceByName(const char* name, libu // Check path only std::string devicePath = getLibusbDevicePath(devs[i]); + // Check if compare with name std::string requiredName(name); if(requiredName.length() > 0 && requiredName == devicePath){ @@ -850,7 +851,6 @@ int usbPlatformConnect(const char *devPathRead, const char *devPathWrite, void * return 0; #endif /*USE_LINK_JTAG*/ #else - libusb_device_handle* usbHandle = nullptr; xLinkPlatformErrorCode_t ret = usbLinkOpen(devPathWrite, usbHandle); @@ -866,6 +866,7 @@ int usbPlatformConnect(const char *devPathRead, const char *devPathWrite, void * #endif /*USE_USB_VSC*/ + return 0; } @@ -938,6 +939,8 @@ int usb_read(libusb_device_handle *f, void *data, size_t size) int usb_write(libusb_device_handle *f, const void *data, size_t size) { + int bt, ss = (int)size; + const int chunk_size = DEFAULT_CHUNKSZ; while(size > 0) { @@ -1021,6 +1024,7 @@ int usbPlatformWrite(void *fdKey, void *data, int size) { return -1; } + while(byteCount < size) { int toWrite = (PACKET_LENGTH && (size - byteCount > PACKET_LENGTH)) \ @@ -1035,6 +1039,7 @@ int usbPlatformWrite(void *fdKey, void *data, int size) byteCount += toWrite; unsigned char acknowledge; int rc; + rc = read(usbFdWrite, &acknowledge, sizeof(acknowledge)); if ( rc < 0) diff --git a/src/pc/protocols/usb_host_ep.cpp b/src/pc/protocols/usb_host_ep.cpp new file mode 100644 index 0000000..6baa4e0 --- /dev/null +++ b/src/pc/protocols/usb_host_ep.cpp @@ -0,0 +1,142 @@ +// project +#include +#define MVLOG_UNIT_NAME xLinkUsb + +#include "XLink/XLinkLog.h" +#include "XLink/XLinkPlatform.h" +#include "XLink/XLinkPublicDefines.h" +#include "usb_host_ep.h" +#include "../PlatformDeviceFd.h" + +#if not defined(_WIN32) +#include +#include + +#include +#include + +struct fdPair { + int usbFdRead; + int usbFdWrite; +}; + +int usbEpInitialize() { + return 0; +} + +int usbEpPlatformConnect(const char *devPathRead, const char *devPathWrite, void **fd) +{ + return X_LINK_ERROR; +} + +int usbEpPlatformServer(const char *devPathRead, const char *devPathWrite, void **fd) +{ + fdPair *pair = new fdPair; + + pair->usbFdRead = -1; + pair->usbFdWrite = -1; + + if(devPathRead != NULL) + { + pair->usbFdRead = open(devPathRead, O_RDONLY); + } + + if(devPathWrite != NULL) + { + pair->usbFdWrite = open(devPathWrite, O_WRONLY); + } + + *fd = createPlatformDeviceFdKey((void*)pair); + + return 0; +} + + +int usbEpPlatformClose(void *fdKey) +{ + fdPair *pair; + getPlatformDeviceFdFromKey(fdKey, (void**)&pair); + + int error; + + if (pair->usbFdRead > -1) { + close(pair->usbFdRead); + pair->usbFdRead = -1; + } + + if (pair->usbFdWrite > -1) { + close(pair->usbFdWrite); + pair->usbFdWrite = -1; + } + + destroyPlatformDeviceFdKey(fdKey); + delete pair; + + return EXIT_SUCCESS; +} + +int usbEpPlatformRead(void *fdKey, void *data, int size) +{ + fdPair *pair; + getPlatformDeviceFdFromKey(fdKey, (void**)&pair); + + int rc = 0; + + if(pair->usbFdRead < 0) + { + return -1; + } + + rc = read(pair->usbFdRead, data, size); + + return rc; +} + +int usbEpPlatformWrite(void *fdKey, void *data, int size) +{ + fdPair *pair; + getPlatformDeviceFdFromKey(fdKey, (void**)&pair); + + int rc = 0; + + if(pair->usbFdWrite < 0) + { + return -1; + } + + rc = write(pair->usbFdWrite, data, size); + return rc; +} + +#else +int usbEpInitialize() { + return X_LINK_ERROR; +} + +int usbEpPlatformConnect(const char *devPathRead, const char *devPathWrite, void **fd) +{ + return X_LINK_ERROR; +} + +int usbEpPlatformServer(const char *devPathRead, const char *devPathWrite, void **fd) +{ + return X_LINK_ERROR; +} + + +int usbEpPlatformClose(void *fdKey) +{ + return X_LINK_ERROR; +} + +int usbEpPlatformRead(void *fdKey, void *data, int size) +{ + return X_LINK_ERROR; +} + +int usbEpPlatformWrite(void *fdKey, void *data, int size) +{ + return X_LINK_ERROR; +} + +#endif diff --git a/src/pc/protocols/usb_host_ep.h b/src/pc/protocols/usb_host_ep.h new file mode 100644 index 0000000..658819d --- /dev/null +++ b/src/pc/protocols/usb_host_ep.h @@ -0,0 +1,24 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "XLink/XLink.h" +#include "XLink/XLinkPlatform.h" + +int usbEpInitialize(); + +int usbEpPlatformConnect(const char *devPathRead, const char *devPathWrite, void **fd); +int usbEpPlatformServer(const char *devPathRead, const char *devPathWrite, void **fd); +int usbEpPlatformClose(void *fd); + +int usbEpPlatformRead(void *fd, void *data, int size); +int usbEpPlatformWrite(void *fd, void *data, int size); + +#ifdef __cplusplus +} +#endif diff --git a/src/shared/XLinkDevice.c b/src/shared/XLinkDevice.c index 4f08964..6f1ecc9 100644 --- a/src/shared/XLinkDevice.c +++ b/src/shared/XLinkDevice.c @@ -212,6 +212,7 @@ XLinkError_t XLinkServerOnly(XLinkHandler_t* handler) link->peerState = XLINK_UP; link->hostClosedFD = 0; handler->linkId = link->id; + return X_LINK_SUCCESS; } @@ -686,6 +687,7 @@ const char* XLinkProtocolToStr(XLinkProtocol_t val) { case X_LINK_PCIE: return "X_LINK_PCIE"; case X_LINK_IPC: return "X_LINK_IPC"; case X_LINK_TCP_IP: return "X_LINK_TCP_IP"; + case X_LINK_USB_EP: return "X_LINK_USB_EP"; case X_LINK_NMB_OF_PROTOCOLS: return "X_LINK_NMB_OF_PROTOCOLS"; case X_LINK_ANY_PROTOCOL: return "X_LINK_ANY_PROTOCOL"; default: @@ -745,4 +747,4 @@ const char* XLinkPCIEBootloaderToStr(XLinkPCIEBootloader val) { // ------------------------------------ // Helpers implementation. End. -// ------------------------------------ \ No newline at end of file +// ------------------------------------