/*
双向
用法:
./udti_EP0_loop_log recv 包长
或者
./udti_EP0_loop_log send 包长
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#include "libusb.h"
//067b:27a1 Prolific Technology, Inc.
#define PL27_VID 0x067b
#define PL27a1_PID 0x27a1
//067b:27a7 Prolific Technology, Inc.
#define PL27a7_PID 0x27a7
#define PL2701_PID 0x2701
//0ea0:7301 Ours Technology, Inc.
#define OTI_VID 0x0ea0
#define OTI_PID 0x7301
#define PL27_BULK_INTF 0
#define BULK_EP0_IN_ADDR 0x89
#define BULK_EP0_OUT_ADDR 0x8
#define PROGRAM_ROLE_SERVER 1
#define PROGRAM_ROLE_CLIENT 2
#define MAX_SEND_COUNTS 1000000
#define MAX_DEV_NUM 100 //最大设备数,最大对拷线条数
// Vendor-specific Requests
#define DEVICE_STATUS_LEN 2 // The byte length of return data from GET_STATUS
#define CONFIG_DEBUG_LOG_FILE "/log/udti_EP0.log"
static int DATA_TRANSFER_SIZE;
static struct libusb_context *g_UsbContext = NULL;
static int g_ProgRole;
FILE *pFileLog = NULL;
//pthread_mutex_t wr_mutex[MAX_DEV_NUM];
pthread_mutex_t w_mutex[MAX_DEV_NUM];
pthread_mutex_t r_mutex[MAX_DEV_NUM];
typedef struct _DEV_STATUS
{
unsigned int pad : 1;
unsigned int localAttached : 1; // Local device was attached when it's 1
unsigned int localSpeed : 1; // Local device is running at super speed (USB 3.0) when it's 1
unsigned int localSuspend : 1; // Local device was suspend when it's 1
unsigned int pad1 : 5;
unsigned int remoteAttached : 1; // Remote device was attached when it's 1
unsigned int remoteSpeed : 1; // Remote device is running at super speed (USB 3.0) when it's 1
unsigned int remoteSuspend : 1; // Remote device was suspend when it's 1
unsigned int pad2 : 4;
} DEV_STATUS;
/*
Get Device Statuses
DEV_STATUS is a 2-byte array. Byte 0 is for local device status and byte 1 is for remote device status.
For each byte, the following bits indicate:
Bit0: suspend bit, 1 represent suspend
Bit1: unplug bit, 1 represent unplug and 0 represent attached
*/
#define VENDOR_SPECIFIC_REQ_GET_STATUS(DEV_HANDLE, DEV_STATUS) \
libusb_control_transfer(DEV_HANDLE, 0xC0, 0xF1, 0, 0, DEV_STATUS, DEVICE_STATUS_LEN, 500)
typedef struct t_UsbDevice
{
unsigned char uchBus; /* bus number */
unsigned char uchDevice; /* device address */
struct libusb_device_handle *pUsbDevice; /* device handle */
double dSendSpeed; /* MB/s */
double dRecvSpeed; /* MB/s */
} UsbDevice_t;
UsbDevice_t atUsbDevice[MAX_DEV_NUM] = {0};
typedef struct libusb_device_handle *devs_handle;
int devs_num; //对拷线数,设备数
/*
* Function prototypes
*/
static int USBOpen(void);
static int USBClose(void);
void *recvTask(void *param);
void *sendTask(void *param);
int reUSBOpen(unsigned char uchBus, unsigned char uchDevice, int iDevIndex, int iWR);/*W:0, R:1*/
void server_on_exit(void)
{
int t = 0;
int res = 0;
fprintf(pFileLog, "server_on_exit. line:%d\n", __LINE__);
fflush(pFileLog);
for (t = 0; t < devs_num; t++)
{
if (atUsbDevice[t].pUsbDevice != NULL)
{
res = libusb_clear_halt(atUsbDevice[t].pUsbDevice, BULK_EP0_IN_ADDR);
fprintf(pFileLog, "libusb_clear_halt:BULK_EP0_IN_ADDR line:%d,res=%d\n", __LINE__, res);
res = libusb_clear_halt(atUsbDevice[t].pUsbDevice, BULK_EP0_OUT_ADDR);
fprintf(pFileLog, "libusb_clear_halt:BULK_EP0_OUT_ADDR line:%d,res=%d\n", __LINE__, res);
res = libusb_reset_device(atUsbDevice[t].pUsbDevice);
fprintf(pFileLog, "libusb_reset_device. line:%d,res=%d\n", __LINE__, res);
fflush(pFileLog);
}
}
}
static void Usage(char const *progName)
{
fprintf(pFileLog, "Usage:\n\t./%s [recv/send] [buffer-size] \n", progName);
fflush(pFileLog);
}
static void SignalHandler(int signum)
{
fprintf(pFileLog, "SignalHandler. line: %d\n", __LINE__);
fprintf(pFileLog, "recv kill signum:%d\n", signum);
fflush(pFileLog);
int t = 0;
int res = 0;
for (t = 0; t < devs_num; t++)
{
if (atUsbDevice[t].pUsbDevice != NULL)
{
//res = libusb_clear_halt(atUsbDevice[t].pUsbDevice, BULK_EP0_IN_ADDR);
//fprintf(pFileLog, "libusb_clear_halt:BULK_EP0_IN_ADDR line:%d,res=%d\n", __LINE__, res);
//res = libusb_clear_halt(atUsbDevice[t].pUsbDevice, BULK_EP0_OUT_ADDR);
//fprintf(pFileLog, "libusb_clear_halt:BULK_EP0_OUT_ADDR line:%d,res=%d\n", __LINE__, res);
res = libusb_reset_device(atUsbDevice[t].pUsbDevice);
fprintf(pFileLog, "libusb_reset_device. line:%d,res=%d\n", __LINE__, res);
fflush(pFileLog);
}
}
}
// #define DEBUG 1
int main(int argc, char *argv[])
{
#ifndef DEBUG
// deamonize, 后台常驻程序 (daemon,也称守护进程)
pid_t pid = fork();
if (pid > 0)
{
// parent exit
printf("run %s in deamon with %d\n", argv[0], pid);
exit(0);
}
// child continue
setsid();
chdir("/"); // 改当前目录为根目录(/)
close(0);
open("/dev/null", O_RDWR);
// no env debug
if (!getenv("debug"))
{
close(1);
close(2);
dup(0);
dup(0);
}
#endif
int res = 0;
pFileLog = fopen(CONFIG_DEBUG_LOG_FILE, "a");
if (NULL == pFileLog)
{
fprintf(stderr, "open CONFIG_DEBUG_LOG_FILE file error!\n");
return -1;
}
fflush(pFileLog);
if (argc < 3)
{
Usage(argv[0]);
goto Exit;
}
else if (strcmp(argv[1], "send") == 0)
{
g_ProgRole = PROGRAM_ROLE_CLIENT;
if (argc < 3)
{
Usage(argv[0]);
goto Exit;
}
}
else if (strcmp(argv[1], "recv") == 0)
{
g_ProgRole = PROGRAM_ROLE_SERVER;
}
else
{
Usage(argv[0]);
goto Exit;
}
// buffersize
if (argv[2])
DATA_TRANSFER_SIZE = atoi(argv[2]);
// Register signals to exit the program.
atexit(server_on_exit);
signal(SIGINT, SignalHandler);
signal(SIGKILL, SignalHandler);
signal(SIGQUIT, SignalHandler);
signal(SIGSTOP, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGTERM, SignalHandler);
signal(SIGPIPE, SIG_IGN);// ignore SIGPIPE
signal(SIGBUS, SignalHandler); // 总线错误
signal(SIGSEGV, SignalHandler); // SIGSEGV,非法内存访问
signal(SIGFPE, SignalHandler); // SIGFPE,数学相关的异常,如被0除,浮点溢出,等等
signal(SIGABRT, SignalHandler); // SIGABRT,由调用abort函数产生,进程非正常退出
devs_num = 0;
// Open the USB device.
res = USBOpen();
if (res != 0)
{
fprintf(pFileLog, "USBOpen fail! res=%d\n", res);
fflush(pFileLog);
goto Exit;
}
fprintf(pFileLog, "USBOpen success!\n");
fflush(pFileLog);
int t = 0;
pthread_t thread_r[MAX_DEV_NUM];
pthread_t thread_s[MAX_DEV_NUM];
for (t = 0; t < devs_num; t++)
{
//pthread_mutex_init (&(wr_mutex[t]), NULL);
pthread_mutex_init (&(w_mutex[t]), NULL);
pthread_mutex_init (&(r_mutex[t]), NULL);
fprintf(pFileLog, "Bus %d Device %d: devs_hdl[%d]=%p\n", atUsbDevice[t].uchBus, atUsbDevice[t].uchDevice, t, atUsbDevice[t].pUsbDevice);
fprintf(pFileLog, "recv Task\n");
fflush(pFileLog);
{
// Create a thread to run server's task.
res = pthread_create(&(thread_r[t]), NULL, recvTask, (void *)&(t));
没有合适的资源?快使用搜索试试~ 我知道了~
建日志目录/log 单向: 先运行./usb_EP0recv_loop_log recv 包长,再运行./udti_EP0send_loop_log send 包长。 双向: ./usb_EP0_loop_log recv 包长 ./usb_EP0_loop_log send 包长
资源推荐
资源详情
资源评论
收起资源包目录
usb_bridge.7z (4个子文件)
usb_bridge
Makefile 577B
usb_EP0send_loop_log.c 26KB
usb_EP0_loop_log.c 37KB
usb_EP0recv_loop_log.c 27KB
共 4 条
- 1
资源评论
109702008
- 粉丝: 1w+
- 资源: 166
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功