usb_diag_lib.c

来自「VC下USB的驱动代码,及其相关操作检测。」· C语言 代码 · 共 966 行 · 第 1/2 页

C
966
字号
        {
            if((dwBytesTransferred == 0) && (recv_frame_len == 0))
            {
                if(RF_USB_RTS)
                {
                    RF_USB_RTS();
                }
                continue;
            }
            
            if(frame_finished)
            {
                frame_finished = 0;

                /* Display operating system-style date and time. */

                LogTime("RX Time:");
            }

            LogHexBuffer(buf, dwBytesTransferred);;
//            PrintHexBuffer(buf, dwBytesTransferred);

            if((recv_frame_len + dwBytesTransferred) > (sizeof(recv_frame_buf)-sizeof(long)))
            {
                recv_frame_len = 0;
            }

            memcpy(((unsigned char *)&recv_frame_buf[0])+recv_frame_len, buf, dwBytesTransferred);
                
            recv_frame_len += dwBytesTransferred;

            if(dwBytesTransferred != 16)
            {
                rc = RF_USB_recv_frame((unsigned char *)&recv_frame_buf[0], recv_frame_len);

                if(rc != 0)
                {
                    printf("CRC ERROR\n");
                }
                
                recv_frame_len = 0;
                frame_finished = 1;
            }
        }

        //flush file
        fflush(log_file);
        
    }
    free(buf);
}


// Function: ListenToPipe()
//   Start listening to a USB device pipe
// Parameters:
//   pListenPipe [in] pipe to listen to
// Return Value:
//   None
void ListenToPipe(USB_LISTEN_PIPE *pListenPipe)
{
    // start the running thread
    pListenPipe->fStopped = FALSE;
    printf("Start listening to pipe\n");

    pListenPipe->dwError = ThreadStart(&pListenPipe->hThread, 
        PipeHandlerThread, (PVOID) pListenPipe);
}

// Function: ListenToPipe()
//   Start listening to a USB device pipe
// Parameters:
//   pListenPipe [in] pipe to listen to
// Return Value:
//   None
void Start_ListenToPipe(DWORD PipeNum)
{
    HANDLE hDevice = _g_hDevice;
    WDU_DEVICE *pDevice;
    USB_LISTEN_PIPE *pListenPipe = & ListenPipe;

    DWORD dwError;
    WDU_ALTERNATE_SETTING *pAltSet;
    WDU_PIPE_INFO *pPipes;

    BYTE i=0;

    if(hDevice == NULL)
    {
        //no device found
        return;
    }

    if(ListenPipe.hDevice != NULL)
    {
        //already started
        return;
    }
        
    dwError = WDU_GetDeviceInfo(hDevice, &pDevice);
    if (dwError)
    {
        ERR("ReadWritePipesMenu: WDU_GetDeviceInfo() failed: error 0x%lx (\"%s\")\n",
            dwError, Stat2Str(dwError));
        return;
    }

    pAltSet = pDevice->pActiveInterface->pActiveAltSetting;
    pPipes = pAltSet->pPipes;

    // search for the pipe
    if (PipeNum)
    {
        for (i=0; i<pAltSet->Descriptor.bNumEndpoints; i++)
            if (pPipes[i].dwNumber==PipeNum)
                break;
        if (i >= pAltSet->Descriptor.bNumEndpoints)
        {
            printf("The pipe number 0x%lx does not exist.\n", PipeNum);
            return;
        }
    }


    BZERO(ListenPipe);
    
    ListenPipe.dwListenPipeNum = PipeNum;
    ListenPipe.dwWritePipeNum = PipeNum & (~0x80);
    
    ListenPipe.hDevice = hDevice;
    ListenPipe.dwPacketSize = pPipes[i].dwMaximumPacketSize;
    
    // start the running thread
    pListenPipe->fStopped = FALSE;
    printf("Start listening to pipe\n");

    recv_frame_len = 0;
    send_frame_len = 0;
    pListenPipe->dwError = ThreadStart(&pListenPipe->hThread, 
        PipeHandlerThread, (PVOID) pListenPipe);
    
}

void Stop_ListenToPipe(DWORD PipeNum)
{
    USB_LISTEN_PIPE *pListenPipe = & ListenPipe;

    if(ListenPipe.hDevice)
    {
        CloseListening(pListenPipe);

        ListenPipe.hDevice = NULL;
    }    
}

// Function: GetHexChar(void)
//   Get next character from user
// Parameters:
//   None
// Return Value:
//   Character received
int GetHexChar(void)
{
    int ch;

    ch = getchar();

    if (!isxdigit(ch))
        return -1;

    if (isdigit(ch))
        return ch - '0';
    else
        return toupper(ch) - 'A' + 10;
}

// Function: GetHexBuffer()
//   Get hex buffer from user
// Parameters:
//   pBuffer [in] pointer to buffer
//   dwBytes [in] length of buffer
// Return Value:
//   Size of buffer received
DWORD GetHexBuffer(PVOID pBuffer, DWORD dwBytes)
{
    DWORD i;
    PBYTE pData = (PBYTE)pBuffer;
    int res;
    int ch;

    for (i=0; i<dwBytes;)
    {
        ch = GetHexChar();
        if (ch<0)
            continue;

        res = ch << 4;

        ch = GetHexChar();
        if (ch<0)
            continue;

        res += ch;
        pData[i] = (BYTE)res;
        i++;
    }

    // advance to new line
    ch=getchar();
    while (1)
    {
        if (ch == '\n' || ch == '\r')
            break;
        ch=getchar();
    }

    // return the number of bytes that was read
    return i;
}

// Function: PrintPipesInfo()
//   Prints the pipes information for the specified alternate setting
// Parameters:
//   pAltSet [in] pointer to the alternate setting information
// Return Value:
//   None
void PrintPipesInfo(WDU_ALTERNATE_SETTING *pAltSet)
{
    BYTE p;
    WDU_PIPE_INFO *pPipe;

    if (!pAltSet->Descriptor.bNumEndpoints)
    {
        printf("  no pipes are defined for this device other than the default pipe (number 0).\n");
        return;
    }
    for (p=0; p<pAltSet->Descriptor.bNumEndpoints; p++)
    {
        pPipe = &pAltSet->pPipes[p];

        printf("  pipe num. 0x%lx: packet size %ld, type %s, dir %s, interval %ld (ms)\n",
            pPipe->dwNumber,
            pPipe->dwMaximumPacketSize,
            pipeType2Str(pPipe->type),
            pPipe->direction==WDU_DIR_IN ? "In" : pPipe->direction==WDU_DIR_OUT ? "Out" : "In & Out",
            pPipe->dwInterval);
    }
}

static void PrintEndpoints(WDU_ALTERNATE_SETTING *pAltSet)
{
    BYTE endp;
    WDU_ENDPOINT_DESCRIPTOR *pEndp;

    for (endp=0; endp<pAltSet->Descriptor.bNumEndpoints; endp++)
    {
        pEndp = &pAltSet->pEndpointDescriptors[endp];
        printf("    end-point address: 0x%02x, attributes: 0x%x, max packet %d, Interval: %d\n",
            pEndp->bEndpointAddress,
            pEndp->bmAttributes,
            pEndp->wMaxPacketSize,
            pEndp->bInterval);
    }
}

// Function: PrintDeviceConfigurations()
//   Prints the device's configurations information
// Parameters:
//   hDevice [in] handle to the USB device
// Return Value:
//   None
void PrintDeviceConfigurations(HANDLE hDevice)
{
    DWORD dwError;
    WDU_DEVICE *pDevice = NULL;
    DWORD ifc, alt;
    UINT32 iConf;

    WDU_CONFIGURATION *pConf;
    WDU_INTERFACE *pInterface;
    WDU_ALTERNATE_SETTING *pAltSet;

    dwError = WDU_GetDeviceInfo(hDevice, &pDevice);
    if (dwError)
    {
        ERR("PrintDeviceConfigurations: WDU_GetDeviceInfo failed: error 0x%lx (\"%s\")\n",
            dwError, Stat2Str(dwError));
        goto Exit;
    }

    printf("This device has %d configurations:\n", pDevice->Descriptor.bNumConfigurations);
    for (iConf=0; iConf<pDevice->Descriptor.bNumConfigurations; iConf++)
    {
        printf("  %d. configuration value %d (has %ld interfaces)\n", 
            iConf, pDevice->pConfigs[iConf].Descriptor.bConfigurationValue,
            pDevice->pConfigs[iConf].dwNumInterfaces);
    }
    iConf = 0;
    if (pDevice->Descriptor.bNumConfigurations>1)
    {
        printf("Please enter the configuration index to display (dec - zero based): ");
        fgets(line, sizeof(line), stdin);
        sscanf(line, "%d", &iConf);
        if (iConf >= pDevice->Descriptor.bNumConfigurations)
        {
            printf("ERROR: invalid configuration index, valid values are 0-%d\n",
                pDevice->Descriptor.bNumConfigurations);
            goto Exit;
        }
    }
    pConf = &pDevice->pConfigs[iConf];

    printf("The configuration indexed %d has %ld interface(s):\n",
        iConf, pConf->dwNumInterfaces);

    for (ifc=0; ifc<pConf->dwNumInterfaces; ifc++)
    {
        pInterface = &pConf->pInterfaces[ifc];
        printf("interface no. %d:\n", 
            pInterface->pAlternateSettings[0].Descriptor.bInterfaceNumber);
        for (alt=0; alt<pInterface->dwNumAltSettings; alt++)
        {
            pAltSet = &pInterface->pAlternateSettings[alt];

            printf("  alternate: %d, endpoints: %d, class: 0x%x, subclass: 0x%x, protocol: 0x%x\n",
                pAltSet->Descriptor.bAlternateSetting,
                pAltSet->Descriptor.bNumEndpoints,
                pAltSet->Descriptor.bInterfaceClass,
                pAltSet->Descriptor.bInterfaceSubClass,
                pAltSet->Descriptor.bInterfaceProtocol);

            PrintEndpoints(pAltSet);
        }
        printf("\n");
    }
    printf("\n");

Exit:
    if (pDevice)
        WDU_PutDeviceInfo(pDevice);
}

// Function: ReadWritePipesMenu()
//   Displays menu to read/write from the device's pipes
// Parameters:
//   hDevice [in] handle to the USB device
// Return Value:
//   None
void ReadWritePipesMenu(HANDLE hDevice)
{
    DWORD dwError;
    WDU_DEVICE *pDevice;
    WDU_ALTERNATE_SETTING *pAltSet;
    WDU_PIPE_INFO *pPipes;
    BYTE  SetupPacket[8];
    DWORD cmd, dwPipeNum, dwSize, dwBytesTransferred;
    BYTE i=0;
    VOID *pBuffer;
    USB_LISTEN_PIPE listenPipe;
    int c;

    dwError = WDU_GetDeviceInfo(hDevice, &pDevice);
    if (dwError)
    {
        ERR("ReadWritePipesMenu: WDU_GetDeviceInfo() failed: error 0x%lx (\"%s\")\n",
            dwError, Stat2Str(dwError));
        return;
    }

    pAltSet = pDevice->pActiveInterface->pActiveAltSetting;
    pPipes = pAltSet->pPipes;

    PrintPipesInfo(pAltSet);

    do {
        printf("\n");
        printf("Read/Write from/to device's pipes\n");
        printf("---------------------\n");
        printf("1.  Read from pipe\n");
        printf("2.  Write to pipe\n");
        printf("3.  Listen to pipe (contiguous read)\n");
        printf("99. Main menu\n");
        printf("Enter option: ");
        cmd = 0;
        fgets(line, sizeof(line), stdin);
        sscanf(line, "%ld", &cmd);

        if (cmd==99)
            break;
        if (cmd<1 || cmd>3)
            continue;

        printf("Please enter the pipe number (hex): 0x");
        fgets(line, sizeof(line), stdin);
        dwPipeNum=0;
        sscanf(line, "%lx", &dwPipeNum);

        // search for the pipe
        if (dwPipeNum)
        {
            for (i=0; i<pAltSet->Descriptor.bNumEndpoints; i++)
                if (pPipes[i].dwNumber==dwPipeNum)
                    break;
            if (i >= pAltSet->Descriptor.bNumEndpoints)
            {
                printf("The pipe number 0x%lx does not exist, please try again.\n", dwPipeNum);
                continue;
            }
        }

        switch (cmd)
        {
        case 1:
        case 2:
            if (!dwPipeNum || pPipes[i].type==PIPE_TYPE_CONTROL)
            {
                printf("Please enter setup packet (hex - 8 bytes): ");
                GetHexBuffer((PVOID) SetupPacket, 8);
            }
            printf("Please enter the size of the buffer (dec):  ");
            fgets(line, sizeof(line), stdin);
            sscanf(line, "%ld", &dwSize);
            pBuffer = malloc(dwSize);
            if (!pBuffer)
            {
                ERR("cannot alloc memory\n");
                break;
            }

            if (cmd==2)
            {
                printf("Please enter the input buffer (hex): ");
                GetHexBuffer(pBuffer, dwSize);
            }
            dwError = WDU_Transfer(hDevice, dwPipeNum? pPipes[i].dwNumber : 0, cmd==1, 0, pBuffer, 
                dwSize, &dwBytesTransferred, SetupPacket, TRANSFER_TIMEOUT);
            if (dwError)
                ERR("ReadWritePipesMenu: WDU_Transfer() failed: error 0x%lx (\"%s\")\n",
                    dwError, Stat2Str(dwError));
            else
            {
                printf("Transferred %ld bytes\n", dwBytesTransferred);
                if (cmd==1)
                    PrintHexBuffer(pBuffer, dwBytesTransferred);
            }
            free(pBuffer);
            break;

        case 3:
            if (!dwPipeNum || pPipes[i].type==PIPE_TYPE_CONTROL)
            {
                printf("Cannot listen to control pipes.\n");
                break;
            }
            BZERO(listenPipe);
            listenPipe.dwListenPipeNum = dwPipeNum;
            listenPipe.hDevice = hDevice;
            listenPipe.dwPacketSize = pPipes[i].dwMaximumPacketSize;

            printf("Press <Enter> to start listening. While listening, press <Enter> to stop\n\n");
            getchar();
            ListenToPipe(&listenPipe);
            if (listenPipe.dwError)
            {
                ERR("ReadWritePipesMenu: error listening to pipe 0x%lx: error 0x%lx (\"%s\")\n",
                    dwPipeNum, listenPipe.dwError, Stat2Str(listenPipe.dwError));
                break;
            }

            while ((c=getchar())!=10) {}   // ESC code
            CloseListening(&listenPipe);
            if (listenPipe.dwError)
                ERR("ReadWritePipesMenu: WDU_Transfer failed: error 0x%lx (\"%s\")\n",
                    listenPipe.dwError, Stat2Str(listenPipe.dwError));
            break;
        }
    } while (1);

    if (pDevice)
        WDU_PutDeviceInfo(pDevice);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?