usbx/test/regression/usbx_msrc_73492_host_vc_header_parse.c
CQ Xiao 6ed7092b77
Add regression tests. (#126)
Add regression tests (auto triggered on PR, manually triggered in forked branch).
2023-11-28 15:50:39 +08:00

1087 lines
37 KiB
C

/* This test is designed to test the simple dpump host/device class operation. */
#include <stdio.h>
#include "tx_api.h"
#include "ux_api.h"
#include "ux_system.h"
#include "ux_utility.h"
#include "fx_api.h"
#include "ux_device_class_dummy.h"
#include "ux_device_stack.h"
#include "ux_host_class_video.h"
#include "ux_test_dcd_sim_slave.h"
#include "ux_test_hcd_sim_host.h"
#include "ux_test_utility_sim.h"
/* Define constants. */
#define UX_DEMO_DEBUG_SIZE (4096*8)
#define UX_DEMO_STACK_SIZE 1024
#define UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
#define UX_DEMO_XMIT_BUFFER_SIZE 512
#define UX_DEMO_RECEPTION_BUFFER_SIZE 512
#define UX_DEMO_FILE_BUFFER_SIZE 512
#define UX_DEMO_RECEPTION_BLOCK_SIZE 64
#define UX_DEMO_MEMORY_SIZE (64*1024)
#define UX_DEMO_FILE_SIZE (128 * 1024)
#define UX_RAM_DISK_MEMORY (256 * 1024)
/* Define local/extern function prototypes. */
static VOID test_thread_entry(ULONG);
static TX_THREAD tx_test_thread_host_simulation;
static TX_THREAD tx_test_thread_slave_simulation;
static VOID tx_test_thread_host_simulation_entry(ULONG);
static VOID tx_test_thread_slave_simulation_entry(ULONG);
static VOID ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params);
static VOID ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params);
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
static VOID ux_test_system_host_enum_hub_function(VOID);
/* Define global data structures. */
UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
UX_HOST_CLASS_VIDEO *host_video = UX_NULL;
ULONG enum_counter;
ULONG error_counter;
ULONG set_cfg_counter;
ULONG rsc_mem_free_on_set_cfg;
ULONG rsc_sem_on_set_cfg;
ULONG rsc_sem_get_on_set_cfg;
ULONG rsc_mutex_on_set_cfg;
ULONG rsc_enum_sem_usage;
ULONG rsc_enum_sem_get_count;
ULONG rsc_enum_mutex_usage;
ULONG rsc_enum_mem_usage;
static UX_DEVICE_CLASS_DUMMY *device_dummy[2] = {UX_NULL, UX_NULL};
static UX_DEVICE_CLASS_DUMMY_PARAMETER device_dummy_parameter;
/* Define device framework. */
#define STRING_FRAMEWORK_LENGTH 47
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
static unsigned char device_framework_full_speed[] = {
/* Device descriptor 18 bytes
0xEF bDeviceClass: Composite class code
0x02 bDeviceSubclass: class sub code
0x00 bDeviceProtocol: Device protocol
idVendor & idProduct - http://www.linux-usb.org/usb.ids
*/
0x12, 0x01, 0x10, 0x01,
0xEF, 0x02, 0x01,
0x08,
0x84, 0x84, 0x00, 0x00,
0x00, 0x01,
0x01, 0x02, 03,
0x01,
/* Configuration 1 descriptor 9 bytes @ 0x12 */
0x09, 0x02,
0xE6, 0x00,
0x02, 0x01, 0x00,
0x40, 0x00,
/* Interface association descriptor @ 0x12+0x09=27 */
0x08, 0x0b, 0x00, 0x02, 0x0E, 0x03, 0x00, 0x00,
/* VideoControl Interface Descriptor Requirement @ 0x12+0x09+8=35 */
0x09, 0x04,
0x00, 0x00,
0x01,
0x0E, 0x01, 0x01,
0x00,
/* VC_HEADER Descriptor @ 35+9=44 */
0x0D, 0x24, 0x01,
0x50, 0x01,
0x4D, 0x00, /* wTotalLength: */
0x00, 0x00, 0x00, 0x00,
0x01, /* bInCollection */
0x01, /* baInterfaceNr(1) */
/* Input Terminal Descriptor (Camera) @ 44+0x0D=57 */
0x12, 0x24, 0x02,
0x02, /* bTerminalID */
0x01, 0x02, /* wTerminalType ITT_CAMERA */
0x00,
0x00,
0x00, 0x00, /* wObjectiveFocalLengthMin */
0x00, 0x00, /* wObjectiveFocalLengthMax */
0x00, 0x00, /* wOcularFocalLength */
0x03, /* bControlSize */
0x00, 0x02, 0x00, /* bmControls */
/* Input Terminal Descriptor (Media Transport) @ 57+0x12=75 */
0x10, 0x24, 0x02,
0x03, /* bTerminalID */
0x02, 0x02, /* wTerminalType ITT_MEDIA_TRANSPORT_INPUT */
0x00,
0x00,
0x01, /* bControlSize */
0x0D, /* bmControls */
0x05, /* bTransportModeSize */
0xAF, 0xFF, 0xFF, 0x7F, 0x00, /* bmTransportModes */
/* Selector Unit Descriptor @ 75+0x10=91 */
0x08, 0x24, 0x04,
0x01, /* bUnitID */
0x02, /* bNrInPins */
0x02, /* baSourceID(1) */
0x03, /* baSourceID(2) */
0x00,
/* Processing Unit Descriptor @ 91+8=99 */
13, 0x24, 0x05,
0x05, /* bUnitID */
0x01, /* bSourceID */
0x00, 0x00, /* wMaxMultiplier */
0x03, /* bControlSize */
0x00, 0x00, 0x00, /* bmControls */
0x00,
0x00, /* bmVideoStandards */
/* Output Terminal Descriptor @ 99+13=112 */
0x09, 0x24, 0x03,
0x04, /* bTerminalID */
0x01, 0x01, /* wTerminalType TT_STREAMING */
0x00,
0x05, /* bSourceID */
0x00,
/* Interrupt Endpoint 0x83 descriptor @ 112+9=121 */
0x07, 0x05, 0x83,
0x03,
0x08, 0x00,
0x0A,
/* CS_ENDPOINT @ 121+7=128 */
0x05, 0x25, 0x03,
0x20, 0x00, /* wMaxTransferSize */
/* VideoStreaming Interface 1.0 @ 128+5=133 */
0x09, 0x04,
0x01, 0x00,
0x01,
0x0E, 0x02, 0x00,
0x00,
/* VS_INPUT_HEADER @ 133+9=142 */
0x0E, 0x24, 0x01,
0x01, /* bNumFormats */
0x4C, 0x00, /* wTotalLength */
0x85, /* bEndpointAddress */
0x00,
0x04, /* bTerminalLink */
0x03, /* bStillCaptureMethod */
0x00, /* bTriggerSupport */
0x00, /* bTriggerUsage */
0x01, /* bControlSize */
0x00, /* bmaControls */
/* VS_FORMAT_MJPEG @ 142+0xE=156 */
0x0B, 0x24, 0x06,
0x01, /* bFormatIndex */
0x01, /* bNumFrameDescriptors */
0x01, /* bmFlags */
0x01, /* bDefaultFrameIndex */
0x00, 0x00,
0x02, /* bmInterlaceFlags */
0x00, /* bCopyProtect */
/* VS_FRAME_MJPEG @ 156+0x0b=167 */
0x1E, 0x24, 0x07,
0x01, /* bFrameIndex */
0x02, /* bmCapabilities */
0xA0, 0x00, /* wWidth 160 */
0x78, 0x00, /* wHeight 120 */
0x00, 0x65, 0x04, 0x00, /* dwMinBitRate */
0x00, 0xA0, 0x0F, 0x00, /* dwMaxBitRate */
0x00, 0x08, 0x00, 0x00, /* dwMaxVideoFrameBufSize */
0x2A, 0x2C, 0x0A, 0x00, /* dwDefaultFrameInterval */
0x01, /* bFrameIntervalType */
0x2A, 0x2C, 0x0A, 0x00, /* dwFrameInterval(1) 666666 */
/* VS_STILL_FRAME @ 167+0x1e=197 */
0x0F, 0x24, 0x03,
0x86, /* bEndpointAddress */
0x02, /* bNumImageSizePatterns */
0x20, 0x03, /* wWidth 800 */
0x58, 0x02, /* wHeight 600 */
0x20, 0x03, /* wWidth */
0x20, 0x03, /* wHeight */
0x01, /* bNumCompressionPtr */
0x64, /* bCompression 1:100 */
/* VS_COLORFORMAT @ 197+0xf=212 */
0x06, 0x24, 0x0D,
0x00, 0x00, 0x00,
/* Bulk endpoint 0x86 */
0x07, 0x05,
0x86,
0x02,
0x40, 0x00,
0x00,
/* VideoStreaming Interface 1.1 */
0x09, 0x04,
0x01, 0x01,
0x02,
0x0E, 0x02, 0x00,
0x00,
/* ISO Endpoint 0x85 */
0x07, 0x05,
0x85,
0x05,
0x80, 0x00, /* 128 */
0x01,
/* Bulk Endpoint 0x86 */
0x07, 0x05,
0x86,
0x02,
0x40, 0x00,
0x00,
};
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
static unsigned char device_framework_high_speed[] = {
/* Device descriptor 18 bytes
0xEF bDeviceClass: Composite class code
0x02 bDeviceSubclass: class sub code
0x00 bDeviceProtocol: Device protocol
idVendor & idProduct - http://www.linux-usb.org/usb.ids
*/
0x12, 0x01, 0x10, 0x01,
0xEF, 0x02, 0x01,
0x08,
0x84, 0x84, 0x00, 0x00,
0x00, 0x01,
0x01, 0x02, 03,
0x01,
/* Configuration 1 descriptor 9 bytes @ 0x12 */
0x09, 0x02,
0xE6, 0x00,
0x02, 0x01, 0x00,
0x40, 0x00,
/* Interface association descriptor @ 0x12+0x09=27 */
0x08, 0x0b, 0x00, 0x02, 0x0E, 0x03, 0x00, 0x00,
/* VideoControl Interface Descriptor Requirement @ 0x12+0x09+8=35 */
0x09, 0x04,
0x00, 0x00,
0x01,
0x0E, 0x01, 0x01,
0x00,
/* VC_HEADER Descriptor @ 35+9=44 */
0x0D, 0x24, 0x01,
0x50, 0x01,
0x4D, 0x00, /* wTotalLength: */
0x00, 0x00, 0x00, 0x00,
0x01, /* bInCollection */
0x01, /* baInterfaceNr(1) */
/* Input Terminal Descriptor (Camera) @ 44+0x0D=57 */
0x12, 0x24, 0x02,
0x02, /* bTerminalID */
0x01, 0x02, /* wTerminalType ITT_CAMERA */
0x00,
0x00,
0x00, 0x00, /* wObjectiveFocalLengthMin */
0x00, 0x00, /* wObjectiveFocalLengthMax */
0x00, 0x00, /* wOcularFocalLength */
0x03, /* bControlSize */
0x00, 0x02, 0x00, /* bmControls */
/* Input Terminal Descriptor (Media Transport) @ 57+0x12=75 */
0x10, 0x24, 0x02,
0x03, /* bTerminalID */
0x02, 0x02, /* wTerminalType ITT_MEDIA_TRANSPORT_INPUT */
0x00,
0x00,
0x01, /* bControlSize */
0x0D, /* bmControls */
0x05, /* bTransportModeSize */
0xAF, 0xFF, 0xFF, 0x7F, 0x00, /* bmTransportModes */
/* Selector Unit Descriptor @ 75+0x10=91 */
0x08, 0x24, 0x04,
0x01, /* bUnitID */
0x02, /* bNrInPins */
0x02, /* baSourceID(1) */
0x03, /* baSourceID(2) */
0x00,
/* Processing Unit Descriptor @ 91+8=99 */
13, 0x24, 0x05,
0x05, /* bUnitID */
0x01, /* bSourceID */
0x00, 0x00, /* wMaxMultiplier */
0x03, /* bControlSize */
0x00, 0x00, 0x00, /* bmControls */
0x00,
0x00, /* bmVideoStandards */
/* Output Terminal Descriptor @ 99+13=112 */
0x09, 0x24, 0x03,
0x04, /* bTerminalID */
0x01, 0x01, /* wTerminalType TT_STREAMING */
0x00,
0x05, /* bSourceID */
0x00,
/* Interrupt Endpoint 0x83 descriptor @ 112+9=121 */
0x07, 0x05, 0x83,
0x03,
0x08, 0x08,
0x01,
/* CS_ENDPOINT @ 121+7=128 */
0x05, 0x25, 0x03,
0x20, 0x00, /* wMaxTransferSize */
/* VideoStreaming Interface 1.0 @ 128+5=133 */
0x09, 0x04,
0x01, 0x00,
0x01,
0x0E, 0x02, 0x00,
0x00,
/* VS_INPUT_HEADER @ 133+9=142 */
0x0E, 0x24, 0x01,
0x01, /* bNumFormats */
0x4C, 0x00, /* wTotalLength */
0x85, /* bEndpointAddress */
0x00,
0x04, /* bTerminalLink */
0x03, /* bStillCaptureMethod */
0x00, /* bTriggerSupport */
0x00, /* bTriggerUsage */
0x01, /* bControlSize */
0x00, /* bmaControls */
/* VS_FORMAT_MJPEG @ 142+0xE=156 */
0x0B, 0x24, 0x06,
0x01, /* bFormatIndex */
0x01, /* bNumFrameDescriptors */
0x01, /* bmFlags */
0x01, /* bDefaultFrameIndex */
0x00, 0x00,
0x02, /* bmInterlaceFlags */
0x00, /* bCopyProtect */
/* VS_FRAME_MJPEG @ 156+0x0b=167 */
0x1E, 0x24, 0x07,
0x01, /* bFrameIndex */
0x02, /* bmCapabilities */
0xA0, 0x00, /* wWidth 160 */
0x78, 0x00, /* wHeight 120 */
0x00, 0x65, 0x04, 0x00, /* dwMinBitRate */
0x00, 0xA0, 0x0F, 0x00, /* dwMaxBitRate */
0x00, 0x08, 0x00, 0x00, /* dwMaxVideoFrameBufSize */
0x2A, 0x2C, 0x0A, 0x00, /* dwDefaultFrameInterval */
0x01, /* bFrameIntervalType */
0x2A, 0x2C, 0x0A, 0x00, /* dwFrameInterval(1) 666666 */
/* VS_STILL_FRAME @ 167+0x1e=197 */
0x0F, 0x24, 0x03,
0x86, /* bEndpointAddress */
0x02, /* bNumImageSizePatterns */
0x20, 0x03, /* wWidth 800 */
0x58, 0x02, /* wHeight 600 */
0x20, 0x03, /* wWidth */
0x20, 0x03, /* wHeight */
0x01, /* bNumCompressionPtr */
0x64, /* bCompression 1:100 */
/* VS_COLORFORMAT @ 197+0xf=212 */
0x06, 0x24, 0x0D,
0x00, 0x00, 0x00,
/* Bulk endpoint 0x86 */
0x07, 0x05,
0x86,
0x02,
0x40, 0x00,
0x00,
/* VideoStreaming Interface 1.1 */
0x09, 0x04,
0x01, 0x01,
0x02,
0x0E, 0x02, 0x00,
0x00,
/* ISO Endpoint 0x85 */
0x07, 0x05,
0x85,
0x05,
0x80, 0x08, /* 2 x 128 = 256 */
0x01,
/* Bulk Endpoint 0x86 */
0x07, 0x05,
0x86,
0x02,
0x40, 0x00,
0x00,
};
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
static unsigned char string_framework[] = {
/* Manufacturer string descriptor : Index 1 - "Express Logic" */
0x09, 0x04, 0x01, 0x0c,
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
0x6f, 0x67, 0x69, 0x63,
/* Product string descriptor : Index 2 - "EL Composite device" */
0x09, 0x04, 0x02, 0x13,
0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
0x69, 0x63, 0x65,
/* Serial Number string descriptor : Index 3 - "0001" */
0x09, 0x04, 0x03, 0x04,
0x30, 0x30, 0x30, 0x31
};
/* Multiple languages are supported on the device, to add
a language besides english, the unicode language code must
be appended to the language_id_framework array and the length
adjusted accordingly. */
static unsigned char language_id_framework[] = {
/* English. */
0x09, 0x04
};
static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
/* Test interactions */
static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
/* function, request to match,
port action, port status,
request action, request EP, request data, request actual length, request status,
status, additional callback,
no_return */
{ UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
UX_FALSE, UX_TEST_PORT_STATUS_DISC,
UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
UX_SUCCESS, ux_test_hcd_entry_set_cfg,
UX_TRUE}, /* Invoke callback & continue */
{ 0 }
};
static UX_TEST_HCD_SIM_ACTION normal_enum_replace[] = {
/* function, request to match,
port action, port status,
request action, request EP, request data, request actual length, request status,
status, additional callback,
no_return */
{ UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
UX_FALSE, 0,
UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 8, 0,
UX_SUCCESS, UX_NULL},
{ UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
UX_FALSE, 0,
UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 18, 0,
UX_SUCCESS, UX_NULL},
{ UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
UX_FALSE, 0,
UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
UX_SUCCESS, UX_NULL},
{ UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
UX_FALSE, 0,
UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 18, 0,
UX_SUCCESS, UX_NULL},
{ 0 }
}
;
/* Define the ISR dispatch. */
extern VOID (*test_isr_dispatch)(void);
/* Prototype for test control return. */
void test_control_return(UINT status);
/* Define the ISR dispatch routine. */
static void test_isr(void)
{
/* For further expansion of interrupt-level testing. */
}
static UINT test_slave_change_function(ULONG change)
{
return 0;
}
static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
{
UX_HOST_CLASS_VIDEO *video_inst = (UX_HOST_CLASS_VIDEO *) inst;
switch(event)
{
case UX_DEVICE_INSERTION:
host_video = video_inst;
break;
case UX_DEVICE_REMOVAL:
host_video = UX_NULL;
break;
default:
break;
}
return 0;
}
static VOID test_dummy_instance_activate(VOID *dummy_instance)
{
if (device_dummy[0] == UX_NULL)
{
device_dummy[0] = (UX_DEVICE_CLASS_DUMMY *)dummy_instance;
return;
}
if (device_dummy[1] == UX_NULL)
{
device_dummy[1] = (UX_DEVICE_CLASS_DUMMY *)dummy_instance;
return;
}
}
static VOID test_dummy_instance_deactivate(VOID *dummy_instance)
{
if (device_dummy[0] == dummy_instance)
device_dummy[0] = UX_NULL;
if (device_dummy[1] == dummy_instance)
device_dummy[1] = UX_NULL;
}
static UX_SLAVE_TRANSFER _last_control_transfer;
static UCHAR _last_control_data[64];
static VOID test_dummy_instance_control_request(UX_DEVICE_CLASS_DUMMY *dummy_instance,
UX_SLAVE_TRANSFER *transfer)
{
USHORT req_length = _ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 6);
#if 0
printf("D_Video_Req %x: %x %x, %x %x %x; %d/%d\n",
transfer->ux_slave_transfer_request_phase,
transfer->ux_slave_transfer_request_setup[0],
transfer->ux_slave_transfer_request_setup[1],
_ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 2),
_ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 4),
_ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 6),
transfer->ux_slave_transfer_request_actual_length,
transfer->ux_slave_transfer_request_requested_length);
#endif
_ux_utility_memory_copy(&_last_control_transfer, transfer, sizeof(UX_SLAVE_TRANSFER));
if (transfer->ux_slave_transfer_request_setup[0] & 0x80) /* GET */
{
_ux_utility_memory_copy(transfer->ux_slave_transfer_request_data_pointer,
_last_control_data,
req_length);
_ux_device_stack_transfer_request(transfer, req_length, req_length);
}
else /* SET */
{
_ux_utility_memory_copy(_last_control_data,
transfer->ux_slave_transfer_request_data_pointer,
req_length);
}
// _ux_device_stack_endpoint_stall(transfer->ux_slave_transfer_request_endpoint);
}
static VOID test_dummy_instance_change(UX_DEVICE_CLASS_DUMMY *dummy_instance)
{
}
static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
{
}
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
{
set_cfg_counter ++;
rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
}
static VOID ux_test_system_host_enum_hub_function(VOID)
{
enum_counter ++;
}
/* Define what the initial system looks like. */
#ifdef CTEST
void test_application_define(void *first_unused_memory)
#else
void usbx_host_class_video_basic_test_application_define(void *first_unused_memory)
#endif
{
UINT status;
CHAR * stack_pointer;
CHAR * memory_pointer;
printf("Running Host Class Video Basic Functionality Test................... ");
#if !(UX_TEST_MULTI_IFC_ON && UX_TEST_MULTI_ALT_ON)
printf("SKIP!\n");
test_control_return(0);
return;
#endif
/* Reset testing counts. */
ux_test_utility_sim_mutex_create_count_reset();
ux_test_utility_sim_sem_create_count_reset();
ux_test_utility_sim_sem_get_count_reset();
/* Reset error generations */
ux_test_utility_sim_sem_error_generation_stop();
ux_test_utility_sim_mutex_error_generation_stop();
ux_test_utility_sim_sem_get_error_generation_stop();
/* Initialize the free memory pointer */
stack_pointer = (CHAR *) usbx_memory;
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
/* Initialize USBX Memory */
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
/* Check for error. */
if (status != UX_SUCCESS)
{
printf(" ERROR #1\n");
test_control_return(1);
}
/* Register the error callback. */
_ux_utility_error_callback_register(test_ux_error_callback);
/* The code below is required for installing the host portion of USBX */
status = ux_host_stack_initialize(test_host_change_function);
if (status != UX_SUCCESS)
{
printf(" ERROR #2\n");
test_control_return(1);
}
/* Register CDC-ACM class. */
status = ux_host_stack_class_register(_ux_system_host_class_video_name, ux_host_class_video_entry);
if (status != UX_SUCCESS)
{
printf(" ERROR #3\n");
test_control_return(1);
}
/* The code below is required for installing the device portion of USBX. No call back for
device status change in this example. */
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
string_framework, STRING_FRAMEWORK_LENGTH,
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,
test_slave_change_function);
if(status!=UX_SUCCESS)
{
printf(" ERROR #5\n");
test_control_return(1);
}
/* Set the parameters for callback when insertion/extraction of a dummy device. */
_ux_utility_memory_set(&device_dummy_parameter, 0, sizeof(device_dummy_parameter));
device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
ux_device_class_dummy_instance_activate = test_dummy_instance_activate;
device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
ux_device_class_dummy_instance_deactivate = test_dummy_instance_deactivate;
device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
ux_device_class_dummy_change = test_dummy_instance_change;
device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
ux_device_class_dummy_control_request = test_dummy_instance_control_request;
/* Initialize the device cdc class. This class owns both interfaces starting with 0. */
status = ux_device_stack_class_register(_ux_system_slave_class_dpump_name,
_ux_device_class_dummy_entry,
1, 0, &device_dummy_parameter);
status |= ux_device_stack_class_register(_ux_system_slave_class_dpump_name,
_ux_device_class_dummy_entry,
1, 1, &device_dummy_parameter);
#if UX_MAX_SLAVE_CLASS_DRIVER > 1
if(status != UX_SUCCESS)
{
printf(" ERROR #7\n");
test_control_return(1);
}
#endif
/* Initialize the simulated device controller. */
status = _ux_test_dcd_sim_slave_initialize();
/* Check for error. */
if (status != TX_SUCCESS)
{
printf(" ERROR #8\n");
test_control_return(1);
}
/* Register all the USB host controllers available in this system */
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
if (status != UX_SUCCESS)
{
printf(" ERROR #4\n");
test_control_return(1);
}
/* Create the main host simulation thread. */
status = tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
stack_pointer, UX_DEMO_STACK_SIZE,
20, 20, 1, TX_AUTO_START);
/* Check for error. */
if (status != TX_SUCCESS)
{
printf(" ERROR #9\n");
test_control_return(1);
}
/* Create the main slave simulation thread. */
status = tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
20, 20, 1, TX_AUTO_START);
/* Check for error. */
if (status != TX_SUCCESS)
{
printf(" ERROR #10\n");
test_control_return(1);
}
}
#define TX_TEST_VIDEO_PARSER_SIZE 32
typedef struct TX_TEST_VIDEO_PARSER_STRUCT
{
UCHAR *descriptor_base;
ULONG parsed_interface[TX_TEST_VIDEO_PARSER_SIZE];
ULONG parsed_entity[TX_TEST_VIDEO_PARSER_SIZE];
ULONG parsed_count;
} TX_TEST_VIDEO_PARSER;
static const TX_TEST_VIDEO_PARSER parser_check =
{
UX_NULL,
{17, 17, 17, 17, 17, 17, 17, 17,
115, 115, 115, 115, 115},
{26, 39, 57, 73, 81, 94, 103, 110,
124, 138, 149, 179, 182},
13
};
static UINT tx_test_video_descriptors_parser(VOID *arg,
UCHAR *packed_interface_descriptor,
UCHAR *packed_entity_descriptor)
{
TX_TEST_VIDEO_PARSER *parser;
parser = (TX_TEST_VIDEO_PARSER *)arg;
parser->parsed_interface[parser->parsed_count] = packed_interface_descriptor - parser->descriptor_base;
parser->parsed_entity [parser->parsed_count] = packed_entity_descriptor - parser->descriptor_base;
parser->parsed_count ++;
}
void tx_test_thread_host_simulation_entry(ULONG arg)
{
UINT status;
ULONG test_n;
ULONG mem_free;
ULONG loop;
TX_TEST_VIDEO_PARSER parser;
ULONG parameter_u32[64/4];
USHORT *parameter_u16 = (USHORT*)parameter_u32;
UCHAR *parameter_u8 = (UCHAR*)parameter_u32;
UX_ENDPOINT *iso_ep;
UX_ENDPOINT *int_ep;
UX_DEVICE *device;
stepinfo("\n");
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
/* Find the video class and wait for the link to be up. */
for (loop = 0; loop < 100; loop ++)
if (host_video != UX_NULL)
break;
if (host_video == UX_NULL)
{
printf("ERROR #%d: enum fail", __LINE__);
test_control_return(1);
}
if (host_video->ux_host_class_video_feature_unit_id != 5)
{
printf("ERROR #%d: wrong feature bUnitID 0x%lx\n", __LINE__, host_video->ux_host_class_video_feature_unit_id);
test_control_return(1);
}
if (host_video->ux_host_class_video_terminal_id != 2)
{
printf("ERROR #%d: wrong input bTerminalID 0x%lx\n", __LINE__, host_video->ux_host_class_video_terminal_id);
test_control_return(1);
}
if (host_video->ux_host_class_video_number_formats != 1)
{
printf("ERROR #%d: wrong VS_HEADER bNumFormats %ld\n", __LINE__, host_video->ux_host_class_video_number_formats);
test_control_return(1);
}
if (host_video->ux_host_class_video_length_formats != 0x004C)
{
printf("ERROR #%d: wrong VS_HEADER wTotalLength 0x%lx\n", __LINE__, host_video->ux_host_class_video_length_formats);
test_control_return(1);
}
if (host_video->ux_host_class_video_format_address !=
(host_video->ux_host_class_video_configuration_descriptor + 124))
{
printf("ERROR #%d: wrong VS_HEADER addr %p <> %p\n", __LINE__,
host_video->ux_host_class_video_format_address,
(host_video->ux_host_class_video_configuration_descriptor + 124));
test_control_return(1);
}
int_ep = host_video->ux_host_class_video_device->
ux_device_current_configuration->
ux_configuration_first_interface->
ux_interface_first_endpoint;
if (int_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length != 8)
{
printf("ERROR #%d: wrong INT max packet length %ld\n", __LINE__, iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length);
test_control_return(1);
}
iso_ep = host_video->ux_host_class_video_device->
ux_device_current_configuration->
ux_configuration_first_interface->
ux_interface_next_interface->
ux_interface_next_interface->ux_interface_first_endpoint;
if (iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length != 128)
{
printf("ERROR #%d: wrong ISO max packet length %ld\n", __LINE__, iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length);
test_control_return(1);
}
/* Re-connect with high speed. */
ux_test_hcd_sim_host_disconnect();
ux_test_dcd_sim_slave_disconnect();
ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
/* Find the video class and wait for the link to be up. */
for (loop = 0; loop < 100; loop ++)
if (host_video != UX_NULL)
break;
if (host_video == UX_NULL)
{
printf("ERROR #%d: enum fail", __LINE__);
test_control_return(1);
}
if (host_video->ux_host_class_video_feature_unit_id != 5)
{
printf("ERROR #%d: wrong feature bUnitID 0x%lx\n", __LINE__, host_video->ux_host_class_video_feature_unit_id);
test_control_return(1);
}
if (host_video->ux_host_class_video_terminal_id != 2)
{
printf("ERROR #%d: wrong input bTerminalID 0x%lx\n", __LINE__, host_video->ux_host_class_video_terminal_id);
test_control_return(1);
}
if (host_video->ux_host_class_video_number_formats != 1)
{
printf("ERROR #%d: wrong VS_HEADER bNumFormats %ld\n", __LINE__, host_video->ux_host_class_video_number_formats);
test_control_return(1);
}
if (host_video->ux_host_class_video_length_formats != 0x004C)
{
printf("ERROR #%d: wrong VS_HEADER wTotalLength 0x%lx\n", __LINE__, host_video->ux_host_class_video_length_formats);
test_control_return(1);
}
if (host_video->ux_host_class_video_format_address !=
(host_video->ux_host_class_video_configuration_descriptor + 124))
{
printf("ERROR #%d: wrong VS_HEADER addr %p <> %p\n", __LINE__,
host_video->ux_host_class_video_format_address,
(host_video->ux_host_class_video_configuration_descriptor + 124));
test_control_return(1);
}
int_ep = host_video->ux_host_class_video_device->
ux_device_current_configuration->
ux_configuration_first_interface->
ux_interface_first_endpoint;
if (int_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length != 8*2)
{
printf("ERROR #%d: wrong INT max packet length %ld\n", __LINE__, iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length);
test_control_return(1);
}
iso_ep = host_video->ux_host_class_video_device->
ux_device_current_configuration->
ux_configuration_first_interface->
ux_interface_next_interface->
ux_interface_next_interface->ux_interface_first_endpoint;
if (iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length != 128*2)
{
printf("ERROR #%d: wrong ISO max packet length %ld\n", __LINE__, iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length);
test_control_return(1);
}
/* Test entities parse. */
ux_utility_memory_set(&parser, 0, sizeof(parser));
parser.descriptor_base = host_video->ux_host_class_video_configuration_descriptor;
status = _ux_host_class_video_entities_parse(host_video, tx_test_video_descriptors_parser, &parser);
if (status != UX_SUCCESS)
{
printf("ERROR #%d: parse error 0x%x\n", __LINE__, status);
test_control_return(1);
}
for(loop = 0; loop < parser.parsed_count; loop++)
{
if (parser.parsed_interface[loop] != parser_check.parsed_interface[loop])
{
printf("ERROR #%d: wrong interface: %ld <> %ld\n", __LINE__,
parser.parsed_interface[loop], parser_check.parsed_interface[loop]);
test_control_return(1);
}
if (parser.parsed_entity[loop] != parser_check.parsed_entity[loop])
{
printf("ERROR #%d: wrong entity descriptor: %ld <> %ld\n", __LINE__,
parser.parsed_entity[loop], parser_check.parsed_entity[loop]);
test_control_return(1);
}
}
/* Test VC_HEADER Descriptor @ device_framework_full_speed[ 35+9=44 ] errors. */
/* Default: bLength = 0x0D (13), bInCollection = 1, baInterfaceNr[0] = 1. */
/* Case 1 : bInCollection @ 11 = 1, baInterfaceNr[0] @ 12 = 5 (interface number not exist). */
ux_test_hcd_sim_host_disconnect();
ux_test_dcd_sim_slave_disconnect();
UX_TEST_ASSERT(host_video == UX_NULL);
device_framework_full_speed[44 + 11] = 1;
device_framework_full_speed[44 + 12] = 5;
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
/* Find the video class and wait for the link to be up. */
for (loop = 0; loop < 100; loop ++)
if (host_video != UX_NULL)
break;
status = ux_host_stack_device_get(0, &device);
UX_TEST_ASSERT(status == UX_SUCCESS && host_video == UX_NULL);
device_framework_full_speed[44 + 11] = 1;
device_framework_full_speed[44 + 12] = 1;
/* Case 2 : bInCollection @ 11 = 3 (over what in configuration). */
ux_test_hcd_sim_host_disconnect();
ux_test_dcd_sim_slave_disconnect();
UX_TEST_ASSERT(host_video == UX_NULL);
device_framework_full_speed[44 + 11] = 3;
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
/* Find the video class and wait for the link to be up. */
for (loop = 0; loop < 100; loop ++)
if (host_video != UX_NULL)
break;
status = ux_host_stack_device_get(0, &device);
UX_TEST_ASSERT(status == UX_SUCCESS && host_video == UX_NULL);
device_framework_full_speed[44 + 11] = 1;
/* Case 3 : bLength @ 0 = 12 (VC header descriptor length too small). */
ux_test_hcd_sim_host_disconnect();
ux_test_dcd_sim_slave_disconnect();
UX_TEST_ASSERT(host_video == UX_NULL);
device_framework_full_speed[44 + 0] = 12;
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
/* Find the video class and wait for the link to be up. */
for (loop = 0; loop < 100; loop ++)
if (host_video != UX_NULL)
break;
status = ux_host_stack_device_get(0, &device);
UX_TEST_ASSERT(status == UX_SUCCESS && host_video == UX_NULL);
device_framework_full_speed[44 + 0] = 13;
/* Test disconnect. */
stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
ux_test_dcd_sim_slave_disconnect();
ux_test_hcd_sim_host_disconnect();
if (host_video != UX_NULL)
{
printf("ERROR #13: instance not removed when disconnect");
test_control_return(1);
}
/* Finally disconnect the device. */
ux_device_stack_disconnect();
/* And deinitialize the class. */
status = ux_device_stack_class_unregister(_ux_system_slave_class_dpump_name, _ux_device_class_dummy_entry);
status |= ux_device_stack_class_unregister(_ux_system_slave_class_dpump_name, _ux_device_class_dummy_entry);
/* Deinitialize the device side of usbx. */
_ux_device_stack_uninitialize();
/* And finally the usbx system resources. */
_ux_system_uninitialize();
/* Successful test. */
printf("SUCCESS!\n");
test_control_return(0);
}
void tx_test_thread_slave_simulation_entry(ULONG arg)
{
while(1)
{
/* Sleep so ThreadX on Win32 will delete this thread. */
tx_thread_sleep(10);
}
}