225 lines
8.6 KiB
C
225 lines
8.6 KiB
C
/**
|
||
********************************************************************
|
||
* @file hal_usb_bulk.c
|
||
* @brief
|
||
*
|
||
* @copyright (c) 2021 DJI. All rights reserved.
|
||
*
|
||
* All information contained herein is, and remains, the property of DJI.
|
||
* The intellectual and technical concepts contained herein are proprietary
|
||
* to DJI and may be covered by U.S. and foreign patents, patents in process,
|
||
* and protected by trade secret or copyright law. Dissemination of this
|
||
* information, including but not limited to data and other proprietary
|
||
* material(s) incorporated within the information, in any form, is strictly
|
||
* prohibited without the express written consent of DJI.
|
||
*
|
||
* If you receive this source code without DJI’s authorization, you may not
|
||
* further disseminate the information, and you must immediately remove the
|
||
* source code and notify DJI of its removal. DJI reserves the right to pursue
|
||
* legal actions against you for any loss(es) or damage(s) caused by your
|
||
* failure to do so.
|
||
*
|
||
*********************************************************************
|
||
*/
|
||
|
||
/* Includes ------------------------------------------------------------------*/
|
||
#include "hal_usb_bulk.h"
|
||
#include "dji_logger.h"
|
||
|
||
/* Private constants ---------------------------------------------------------*/
|
||
#define LINUX_USB_BULK_TRANSFER_TIMEOUT_MS (50)
|
||
#define LINUX_USB_BULK_TRANSFER_WAIT_FOREVER (-1)
|
||
|
||
/* Private types -------------------------------------------------------------*/
|
||
typedef struct {
|
||
#ifdef LIBUSB_INSTALLED
|
||
libusb_device_handle *handle;
|
||
#else
|
||
void *handle;
|
||
#endif
|
||
int32_t ep1;
|
||
int32_t ep2;
|
||
uint32_t interfaceNum;
|
||
T_DjiHalUsbBulkInfo usbBulkInfo;
|
||
} T_HalUsbBulkObj;
|
||
|
||
/* Private values -------------------------------------------------------------*/
|
||
|
||
/* Private functions declaration ---------------------------------------------*/
|
||
|
||
/* Exported functions definition ---------------------------------------------*/
|
||
T_DjiReturnCode HalUsbBulk_Init(T_DjiHalUsbBulkInfo usbBulkInfo, T_DjiUsbBulkHandle *usbBulkHandle)
|
||
{
|
||
int32_t ret;
|
||
struct libusb_device_handle *handle = NULL;
|
||
|
||
*usbBulkHandle = malloc(sizeof(T_HalUsbBulkObj));
|
||
if (*usbBulkHandle == NULL) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
if (usbBulkInfo.isUsbHost == true) {
|
||
#ifdef LIBUSB_INSTALLED
|
||
ret = libusb_init(NULL);
|
||
if (ret < 0) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
handle = libusb_open_device_with_vid_pid(NULL, usbBulkInfo.vid, usbBulkInfo.pid);
|
||
if (handle == NULL) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
ret = libusb_claim_interface(handle, usbBulkInfo.channelInfo.interfaceNum);
|
||
if (ret != LIBUSB_SUCCESS) {
|
||
printf("libusb claim interface error");
|
||
libusb_close(handle);
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
((T_HalUsbBulkObj *) *usbBulkHandle)->handle = handle;
|
||
memcpy(&((T_HalUsbBulkObj *) *usbBulkHandle)->usbBulkInfo, &usbBulkInfo, sizeof(usbBulkInfo));
|
||
#endif
|
||
} else {
|
||
((T_HalUsbBulkObj *) *usbBulkHandle)->handle = handle;
|
||
memcpy(&((T_HalUsbBulkObj *) *usbBulkHandle)->usbBulkInfo, &usbBulkInfo, sizeof(usbBulkInfo));
|
||
((T_HalUsbBulkObj *) *usbBulkHandle)->interfaceNum = usbBulkInfo.channelInfo.interfaceNum;
|
||
|
||
if (usbBulkInfo.channelInfo.interfaceNum == LINUX_USB_BULK1_INTERFACE_NUM) {
|
||
((T_HalUsbBulkObj *) *usbBulkHandle)->ep1 = open(LINUX_USB_BULK1_EP_OUT_FD, O_RDWR);
|
||
if (((T_HalUsbBulkObj *) *usbBulkHandle)->ep1 < 0) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
((T_HalUsbBulkObj *) *usbBulkHandle)->ep2 = open(LINUX_USB_BULK1_EP_IN_FD, O_RDWR);
|
||
if (((T_HalUsbBulkObj *) *usbBulkHandle)->ep2 < 0) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
} else if (usbBulkInfo.channelInfo.interfaceNum == LINUX_USB_BULK2_INTERFACE_NUM) {
|
||
((T_HalUsbBulkObj *) *usbBulkHandle)->ep1 = open(LINUX_USB_BULK2_EP_OUT_FD, O_RDWR);
|
||
if (((T_HalUsbBulkObj *) *usbBulkHandle)->ep1 < 0) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
((T_HalUsbBulkObj *) *usbBulkHandle)->ep2 = open(LINUX_USB_BULK2_EP_IN_FD, O_RDWR);
|
||
if (((T_HalUsbBulkObj *) *usbBulkHandle)->ep2 < 0) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
}
|
||
}
|
||
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
||
}
|
||
|
||
T_DjiReturnCode HalUsbBulk_DeInit(T_DjiUsbBulkHandle usbBulkHandle)
|
||
{
|
||
struct libusb_device_handle *handle = NULL;
|
||
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
|
||
|
||
if (usbBulkHandle == NULL) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
handle = ((T_HalUsbBulkObj *) usbBulkHandle)->handle;
|
||
|
||
if (((T_HalUsbBulkObj *) usbBulkHandle)->usbBulkInfo.isUsbHost == true) {
|
||
#ifdef LIBUSB_INSTALLED
|
||
libusb_release_interface(handle, ((T_HalUsbBulkObj *) usbBulkHandle)->usbBulkInfo.channelInfo.interfaceNum);
|
||
osalHandler->TaskSleepMs(100);
|
||
libusb_exit(NULL);
|
||
#endif
|
||
} else {
|
||
close(((T_HalUsbBulkObj *) usbBulkHandle)->ep1);
|
||
close(((T_HalUsbBulkObj *) usbBulkHandle)->ep2);
|
||
}
|
||
|
||
free(usbBulkHandle);
|
||
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
||
}
|
||
|
||
T_DjiReturnCode HalUsbBulk_WriteData(T_DjiUsbBulkHandle usbBulkHandle, const uint8_t *buf, uint32_t len,
|
||
uint32_t *realLen)
|
||
{
|
||
int32_t ret;
|
||
int32_t actualLen;
|
||
struct libusb_device_handle *handle = NULL;
|
||
|
||
if (usbBulkHandle == NULL) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
handle = ((T_HalUsbBulkObj *) usbBulkHandle)->handle;
|
||
|
||
if (((T_HalUsbBulkObj *) usbBulkHandle)->usbBulkInfo.isUsbHost == true) {
|
||
#ifdef LIBUSB_INSTALLED
|
||
ret = libusb_bulk_transfer(handle, ((T_HalUsbBulkObj *) usbBulkHandle)->usbBulkInfo.channelInfo.endPointOut,
|
||
(uint8_t *) buf, len, &actualLen, LINUX_USB_BULK_TRANSFER_TIMEOUT_MS);
|
||
if (ret < 0) {
|
||
USER_LOG_ERROR("Write usb bulk data failed, errno = %d", ret);
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
*realLen = actualLen;
|
||
#endif
|
||
} else {
|
||
*realLen = write(((T_HalUsbBulkObj *) usbBulkHandle)->ep1, buf, len);
|
||
}
|
||
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
||
}
|
||
|
||
T_DjiReturnCode HalUsbBulk_ReadData(T_DjiUsbBulkHandle usbBulkHandle, uint8_t *buf, uint32_t len,
|
||
uint32_t *realLen)
|
||
{
|
||
int32_t ret;
|
||
struct libusb_device_handle *handle = NULL;
|
||
int32_t actualLen;
|
||
|
||
if (usbBulkHandle == NULL) {
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
handle = ((T_HalUsbBulkObj *) usbBulkHandle)->handle;
|
||
|
||
if (((T_HalUsbBulkObj *) usbBulkHandle)->usbBulkInfo.isUsbHost == true) {
|
||
#ifdef LIBUSB_INSTALLED
|
||
ret = libusb_bulk_transfer(handle, ((T_HalUsbBulkObj *) usbBulkHandle)->usbBulkInfo.channelInfo.endPointIn,
|
||
buf, len, &actualLen, LINUX_USB_BULK_TRANSFER_WAIT_FOREVER);
|
||
if (ret < 0) {
|
||
USER_LOG_ERROR("Read usb bulk data failed, errno = %d", ret);
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
|
||
}
|
||
|
||
*realLen = actualLen;
|
||
#endif
|
||
} else {
|
||
*realLen = read(((T_HalUsbBulkObj *) usbBulkHandle)->ep2, buf, len);
|
||
}
|
||
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
||
}
|
||
|
||
T_DjiReturnCode HalUsbBulk_GetDeviceInfo(T_DjiHalUsbBulkDeviceInfo *deviceInfo)
|
||
{
|
||
//attention: this interface only be called in usb device mode.
|
||
deviceInfo->vid = LINUX_USB_VID;
|
||
deviceInfo->pid = LINUX_USB_PID;
|
||
|
||
// This bulk channel is used to obtain DJI camera video stream and push 3rd-party camera video stream.
|
||
deviceInfo->channelInfo[DJI_HAL_USB_BULK_NUM_0].interfaceNum = LINUX_USB_BULK1_INTERFACE_NUM;
|
||
deviceInfo->channelInfo[DJI_HAL_USB_BULK_NUM_0].endPointIn = LINUX_USB_BULK1_END_POINT_IN;
|
||
deviceInfo->channelInfo[DJI_HAL_USB_BULK_NUM_0].endPointOut = LINUX_USB_BULK1_END_POINT_OUT;
|
||
|
||
// This bulk channel is used to obtain DJI perception image and download camera media file.
|
||
deviceInfo->channelInfo[DJI_HAL_USB_BULK_NUM_1].interfaceNum = LINUX_USB_BULK2_INTERFACE_NUM;
|
||
deviceInfo->channelInfo[DJI_HAL_USB_BULK_NUM_1].endPointIn = LINUX_USB_BULK2_END_POINT_IN;
|
||
deviceInfo->channelInfo[DJI_HAL_USB_BULK_NUM_1].endPointOut = LINUX_USB_BULK2_END_POINT_OUT;
|
||
|
||
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
||
}
|
||
|
||
/* Private functions definition-----------------------------------------------*/
|
||
|
||
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/
|