usbTargKbdLib.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:15k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* usbTargKbdLib.c - USB keyboard target exerciser/demonstration */
  2. /* Copyright 2000 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01b,23nov99,rcb  Change #include ../xxx references to lower case.
  7. 01a,18aug99,rcb  First.
  8. */
  9. /*
  10. DESCRIPTION
  11. This module contains code to exercise the usbTargLib by emulating a rudimentary
  12. USB keyboard.  This module will generally be invoked by usbTool or a similar USB
  13. test/exerciser application.
  14. It is the caller's responsibility to initialize usbTargLib and attach a USB TCD 
  15. to it. When attaching a TCD to usbTargLib, the caller must pass a pointer to a
  16. table of callbacks required by usbTargLib.  The address of this table and the
  17. "callback parameter" required by these callbacks may be obtained by calling
  18. usbTargKbdCallbackInfo().  It is not necessary to initialize the usbTartKbdLib or
  19. to shut it down.  It performs all of its operations in response to callbacks from
  20. usbTargLib.
  21. This module also exports a function called usbTargKbdInjectReport().  This 
  22. function allows the caller to inject a "boot report" into the interrupt pipe.
  23. This allows for rudimentary emulation of keystrokes.
  24. */
  25. /* includes */
  26. #include "usb/usbPlatform.h"
  27. #include "string.h"
  28. #include "usb/usb.h"
  29. #include "usb/usbHid.h"      /* USB HID definitions */
  30. #include "usb/usbDescrCopyLib.h" /* USB utility functions */
  31. #include "usb/target/usbTargLib.h"     /* USB target functions */
  32. #include "drv/usb/target/usbTargKbdLib.h"   /* our API */
  33. /* defines */
  34. /* string identifiers */
  35. #define UNICODE_ENGLISH     0x409
  36. #define ID_STR_MFG     1
  37. #define ID_STR_MFG_VAL     "Wind River Systems"
  38. #define ID_STR_PROD     2
  39. #define ID_STR_PROD_VAL     "USB keyboard emulator"
  40. /* keyboard device */
  41. #define KBD_USB_VERSION  0x0100
  42. #define KBD_NUM_CONFIG 1
  43. /* keyboard configuration */
  44. #define KBD_CONFIG_VALUE 1
  45. #define KBD_NUM_INTERFACES 1
  46. /* keyboard interface */
  47. #define KBD_INTERFACE_NUM 0
  48. #define KBD_INTERFACE_ALT_SETTING 1
  49. #define KBD_NUM_ENDPOINTS 1
  50. /* keyboard interrupt endpoint */
  51. #define KBD_INTERRUPT_ENDPOINT_NUM 0x01
  52. #define KBD_INTERRUPT_ENDPOINT_INTERVAL 20 /* 20 milliseconds */
  53. /* typedefs */
  54. /* forward declarations */
  55. LOCAL STATUS mngmtFunc
  56.     (
  57.     pVOID param,
  58.     USB_TARG_CHANNEL targChannel,
  59.     UINT16 mngmtCode
  60.     );
  61. LOCAL STATUS featureClear
  62.     (
  63.     pVOID param,
  64.     USB_TARG_CHANNEL targChannel,
  65.     UINT8 requestType,
  66.     UINT16 feature,
  67.     UINT16 index
  68.     );
  69. LOCAL STATUS featureSet
  70.     (
  71.     pVOID param,
  72.     USB_TARG_CHANNEL targChannel,
  73.     UINT8 requestType,
  74.     UINT16 feature,
  75.     UINT16 index
  76.     );
  77. LOCAL STATUS configurationGet
  78.     (
  79.     pVOID param,
  80.     USB_TARG_CHANNEL targChannel,
  81.     pUINT8 pConfiguration
  82.     );
  83. LOCAL STATUS configurationSet
  84.     (
  85.     pVOID param,
  86.     USB_TARG_CHANNEL targChannel,
  87.     UINT8 configuration
  88.     );
  89. LOCAL STATUS descriptorGet
  90.     (
  91.     pVOID param,
  92.     USB_TARG_CHANNEL targChannel,
  93.     UINT8 requestType,
  94.     UINT8 descriptorType,
  95.     UINT8 descriptorIndex,
  96.     UINT16 languageId,
  97.     UINT16 length,
  98.     pUINT8 pBfr,
  99.     pUINT16 pActLen
  100.     );
  101. LOCAL STATUS interfaceGet
  102.     (
  103.     pVOID param,
  104.     USB_TARG_CHANNEL targChannel,
  105.     UINT16 interfaceIndex,
  106.     pUINT8 pAlternateSetting
  107.     );
  108. LOCAL STATUS interfaceSet
  109.     (
  110.     pVOID param,
  111.     USB_TARG_CHANNEL targChannel,
  112.     UINT16 interfaceIndex,
  113.     UINT8 alternateSetting
  114.     );
  115. LOCAL STATUS vendorSpecific
  116.     (
  117.     pVOID param,
  118.     USB_TARG_CHANNEL targChannel,
  119.     UINT8 requestType,
  120.     UINT8 request,
  121.     UINT16 value,
  122.     UINT16 index,
  123.     UINT16 length
  124.     );
  125. /* locals */
  126. LOCAL USB_TARG_CALLBACK_TABLE usbTargKbdCallbackTable =
  127.     {
  128.     mngmtFunc, /* mngmtFunc */
  129.     featureClear, /* featureClear */
  130.     featureSet,  /* featureSet */
  131.     configurationGet, /* configurationGet */
  132.     configurationSet, /* configurationSet */
  133.     descriptorGet, /* descriptorGet */
  134.     NULL, /* descriptorSet */
  135.     interfaceGet, /* interfaceGet */
  136.     interfaceSet, /* interfaceSet */
  137.     NULL, /* statusGet */
  138.     NULL, /* addressSet */
  139.     NULL, /* synchFrameGet */
  140.     vendorSpecific, /* vendorSpecific */
  141.     };
  142. LOCAL USB_TARG_CHANNEL channel;
  143. LOCAL UINT16 numEndpoints;
  144. LOCAL pUSB_TARG_ENDPOINT_INFO pEndpoints;
  145. LOCAL UINT8 curConfiguration;
  146. LOCAL UINT8 curAlternateSetting;
  147. LOCAL USB_TARG_PIPE intPipeHandle;
  148. LOCAL USB_ERP reportErp;
  149. LOCAL BOOL reportInUse;
  150. LOCAL HID_KBD_BOOT_REPORT reportBfr;
  151. LOCAL USB_LANGUAGE_DESCR langDescr =
  152.     {sizeof (USB_LANGUAGE_DESCR), USB_DESCR_STRING, 
  153. {TO_LITTLEW (UNICODE_ENGLISH)}};
  154. LOCAL char *pStrMfg = ID_STR_MFG_VAL;
  155. LOCAL char *pStrProd = ID_STR_PROD_VAL;
  156. LOCAL USB_DEVICE_DESCR devDescr =
  157.     {
  158.     USB_DEVICE_DESCR_LEN,     /* bLength */
  159.     USB_DESCR_DEVICE,     /* bDescriptorType */
  160.     TO_LITTLEW (KBD_USB_VERSION),   /* bcdUsb */
  161.     0,     /* bDeviceClass */
  162.     0,     /* bDeviceSubclass */
  163.     0,     /* bDeviceProtocol */
  164.     USB_MIN_CTRL_PACKET_SIZE,     /* maxPacketSize0 */
  165.     0,     /* idVendor */
  166.     0,     /* idProduct */
  167.     0,     /* bcdDevice */
  168.     ID_STR_MFG,      /* iManufacturer */
  169.     ID_STR_PROD,     /* iProduct */
  170.     0,     /* iSerialNumber */
  171.     KBD_NUM_CONFIG     /* bNumConfigurations */
  172.     };
  173. LOCAL USB_CONFIG_DESCR configDescr =
  174.     {
  175.     USB_CONFIG_DESCR_LEN,     /* bLength */
  176.     USB_DESCR_CONFIGURATION,     /* bDescriptorType */
  177.     TO_LITTLEW (USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN + 
  178.     USB_ENDPOINT_DESCR_LEN),
  179.     /* wTotalLength */
  180.     KBD_NUM_INTERFACES,      /* bNumInterfaces */
  181.     KBD_CONFIG_VALUE,     /* bConfigurationValue */
  182.     0,     /* iConfiguration */
  183.     USB_ATTR_SELF_POWERED,     /* bmAttributes */
  184.     0     /* MaxPower */
  185.     };
  186. LOCAL USB_INTERFACE_DESCR ifDescr =
  187.     {
  188.     USB_INTERFACE_DESCR_LEN,     /* bLength */
  189.     USB_DESCR_INTERFACE,     /* bDescriptorType */
  190.     KBD_INTERFACE_NUM,     /* bInterfaceNumber */
  191.     KBD_INTERFACE_ALT_SETTING,     /* bAlternateSetting */
  192.     KBD_NUM_ENDPOINTS,     /* bNumEndpoints */
  193.     USB_CLASS_HID,     /* bInterfaceClass */
  194.     USB_SUBCLASS_HID_BOOT,     /* bInterfaceSubClass */
  195.     USB_PROTOCOL_HID_BOOT_KEYBOARD, /* bInterfaceProtocol */
  196.     0     /* iInterface */
  197.     };
  198. LOCAL USB_ENDPOINT_DESCR epDescr =
  199.     {
  200.     USB_ENDPOINT_DESCR_LEN,     /* bLength */
  201.     USB_DESCR_ENDPOINT,      /* bDescriptorType */
  202.     KBD_INTERRUPT_ENDPOINT_NUM,     /* bEndpointAddress */
  203.     USB_ATTR_INTERRUPT,      /* bmAttributes */
  204.     sizeof (HID_KBD_BOOT_REPORT),   /* maxPacketSize */
  205.     KBD_INTERRUPT_ENDPOINT_INTERVAL /* bInterval */
  206.     };
  207. /* functions */
  208. /***************************************************************************
  209. *
  210. * usbTargKbdCallbackInfo - returns usbTargKbdLib callback table
  211. *
  212. * RETURNS: N/A
  213. */
  214. VOID usbTargKbdCallbackInfo
  215.     (
  216.     pUSB_TARG_CALLBACK_TABLE *ppCallbacks,
  217.     pVOID *pCallbackParam
  218.     )
  219.     {
  220.     if (ppCallbacks != NULL)
  221. *ppCallbacks = &usbTargKbdCallbackTable;
  222.     if (pCallbackParam != NULL)
  223. *pCallbackParam = NULL;
  224.     }
  225. /***************************************************************************
  226. *
  227. * reportErpCallback - called when report ERP terminates
  228. *
  229. * RETURNS: N/A
  230. */
  231. LOCAL VOID reportErpCallback
  232.     (
  233.     pVOID p /* pointer to ERP */
  234.     )
  235.     {
  236.     reportInUse = FALSE;
  237.     }
  238. /***************************************************************************
  239. *
  240. * usbTargKbdInjectReport - injects a "boot report" into the interrupt pipe
  241. *
  242. * RETURNS: OK, or ERROR if unable to inject report
  243. */
  244. STATUS usbTargKbdInjectReport
  245.     (
  246.     pHID_KBD_BOOT_REPORT pReport,
  247.     UINT16 reportLen
  248.     )
  249.     {
  250.     /* If the report pipe isn't enabled, return an error. */
  251.     if (intPipeHandle == NULL)
  252. return ERROR;
  253.     /* If a report is already queued, return an error. */
  254.     if (reportInUse)
  255. return ERROR;
  256.     reportInUse = TRUE;
  257.     /* Copy the report and set up the transfer. */
  258.     reportLen = min (sizeof (reportBfr), reportLen);
  259.     memcpy (&reportBfr, pReport, reportLen);
  260.     memset (&reportErp, 0, sizeof (reportErp));
  261.     reportErp.erpLen = sizeof (reportErp);
  262.     reportErp.userCallback = reportErpCallback;
  263.     reportErp.bfrCount = 1;
  264.     reportErp.bfrList [0].pid = USB_PID_IN;
  265.     reportErp.bfrList [0].pBfr = (pUINT8) &reportBfr;
  266.     reportErp.bfrList [0].bfrLen = reportLen;
  267.     return usbTargTransfer (intPipeHandle, &reportErp);
  268.     }
  269. /***************************************************************************
  270. *
  271. * mngmtFunc - invoked by usbTargLib for connection management events
  272. *
  273. * RETURNS: OK if able to handle event, or ERROR if unable to handle event
  274. */
  275. LOCAL STATUS mngmtFunc
  276.     (
  277.     pVOID param,
  278.     USB_TARG_CHANNEL targChannel,
  279.     UINT16 mngmtCode     /* management code */
  280.     )
  281.     {
  282.     switch (mngmtCode)
  283. {
  284. case TCD_MNGMT_ATTACH:
  285.     /* Initialize global data */
  286.     channel = targChannel;
  287.     usbTargEndpointInfoGet (targChannel, &numEndpoints, &pEndpoints);
  288.     curConfiguration = 0;
  289.     curAlternateSetting = 0;
  290.     intPipeHandle = NULL;
  291.     /* Initialize control pipe maxPacketSize. */
  292.     devDescr.maxPacketSize0 = pEndpoints [0].maxPacketSize;
  293.     break;
  294. case TCD_MNGMT_DETACH:
  295.     break;
  296. case TCD_MNGMT_BUS_RESET:
  297. case TCD_MNGMT_VBUS_LOST:
  298.     /* revert to power-ON configuration */
  299.     configurationSet (param, targChannel, 0);
  300.     break;     
  301. default:
  302.     break;
  303. }
  304.     return OK;
  305.     }
  306. /***************************************************************************
  307. *
  308. * featureClear - invoked by usbTargLib for CLEAR_FEATURE request
  309. *
  310. * RETURNS: OK, or ERROR if unable to clear requested feature
  311. */
  312. LOCAL STATUS featureClear
  313.     (
  314.     pVOID param,
  315.     USB_TARG_CHANNEL targChannel,
  316.     UINT8 requestType,
  317.     UINT16 feature,
  318.     UINT16 index
  319.     )
  320.     {
  321.     return OK;
  322.     }
  323. /***************************************************************************
  324. *
  325. * featureSet - invoked by usbTargLib for SET_FEATURE request
  326. *
  327. * RETURNS: OK, or ERROR if unable to set requested feature
  328. */
  329. LOCAL STATUS featureSet
  330.     (
  331.     pVOID param,
  332.     USB_TARG_CHANNEL targChannel,
  333.     UINT8 requestType,
  334.     UINT16 feature,
  335.     UINT16 index
  336.     )
  337.     {
  338.     return OK;
  339.     }
  340. /***************************************************************************
  341. *
  342. * configurationGet - invoked by usbTargLib for GET_CONFIGURATION request
  343. *
  344. * RETURNS: OK, or ERROR if unable to return configuration setting
  345. */
  346. LOCAL STATUS configurationGet
  347.     (
  348.     pVOID param,
  349.     USB_TARG_CHANNEL targChannel,
  350.     pUINT8 pConfiguration
  351.     )
  352.     {
  353.     *pConfiguration = curConfiguration;
  354.     return OK;
  355.     }
  356. /***************************************************************************
  357. *
  358. * configurationSet - invoked by usbTargLib for SET_CONFIGURATION request
  359. *
  360. * RETURNS: OK, or ERROR if unable to set specified configuration
  361. */
  362. LOCAL STATUS configurationSet
  363.     (
  364.     pVOID param,
  365.     USB_TARG_CHANNEL targChannel,
  366.     UINT8 configuration
  367.     )
  368.     {
  369.     UINT16 i;
  370.     if (configuration > KBD_CONFIG_VALUE)
  371. return ERROR;
  372.     if ((curConfiguration = configuration) == KBD_CONFIG_VALUE)
  373. {
  374. /* Enable the interrupt status pipe if not already enabled. */
  375. if (intPipeHandle == NULL)
  376.     {
  377.     /* Find a suitable endpoint */
  378.     for (i = 2; i < numEndpoints; i++)
  379. if ((pEndpoints [i].flags & TCD_ENDPOINT_INT_OK) != 0 &&
  380.     (pEndpoints [i].flags & TCD_ENDPOINT_IN_OK) != 0)
  381.     break;
  382.     if (i == numEndpoints)
  383. return ERROR;
  384.     /* Create a pipe */
  385.     if (usbTargPipeCreate (targChannel, pEndpoints [i].endpointId, 0,
  386. KBD_INTERRUPT_ENDPOINT_NUM, configuration, KBD_INTERFACE_NUM, 
  387. USB_XFRTYPE_INTERRUPT, USB_DIR_IN, &intPipeHandle) != OK)
  388. return ERROR;
  389.     reportInUse = FALSE;
  390.     }
  391. }
  392.     else
  393. {
  394. /* Disable the interrupt status pipe if it's enabled */
  395. if (intPipeHandle != NULL)
  396.     {
  397.     usbTargPipeDestroy (intPipeHandle);
  398.     intPipeHandle = NULL;
  399.     }
  400. }
  401.     return OK;
  402.     }
  403. /***************************************************************************
  404. *
  405. * descriptorGet - invoked by usbTargLib for GET_DESCRIPTOR request
  406. *
  407. * RETURNS: OK, or ERROR if unable to return requested descriptor
  408. */
  409. LOCAL STATUS descriptorGet
  410.     (
  411.     pVOID param,
  412.     USB_TARG_CHANNEL targChannel,
  413.     UINT8 requestType,
  414.     UINT8 descriptorType,
  415.     UINT8 descriptorIndex,
  416.     UINT16 languageId,
  417.     UINT16 length,
  418.     pUINT8 pBfr,
  419.     pUINT16 pActLen
  420.     )
  421.     {
  422.     UINT8 bfr [USB_MAX_DESCR_LEN];
  423.     UINT16 actLen;
  424.     /* Determine type of descriptor being requested. */
  425.     if (requestType == (USB_RT_DEV_TO_HOST | USB_RT_STANDARD | USB_RT_DEVICE))
  426. {
  427. switch (descriptorType)
  428.     {
  429.     case USB_DESCR_DEVICE:  
  430. usbDescrCopy (pBfr, &devDescr, length, pActLen);
  431. break;
  432.     case USB_DESCR_CONFIGURATION:
  433. memcpy (bfr, &configDescr, USB_CONFIG_DESCR_LEN);
  434. memcpy (&bfr [USB_CONFIG_DESCR_LEN], &ifDescr,
  435.     USB_INTERFACE_DESCR_LEN);
  436. memcpy (&bfr [USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN],
  437.     &epDescr, USB_ENDPOINT_DESCR_LEN);
  438. actLen = min (length, USB_CONFIG_DESCR_LEN +
  439.     USB_INTERFACE_DESCR_LEN + USB_ENDPOINT_DESCR_LEN);
  440. memcpy (pBfr, bfr, actLen);
  441. *pActLen = actLen;
  442. break;
  443.     case USB_DESCR_INTERFACE:
  444. usbDescrCopy (pBfr, &ifDescr, length, pActLen);
  445. break;
  446.     case USB_DESCR_ENDPOINT:
  447. usbDescrCopy (pBfr, &epDescr, length, pActLen);
  448. break;
  449.     
  450.     case USB_DESCR_STRING:
  451. switch (descriptorIndex)
  452.     {
  453.     case 0: /* language descriptor */
  454. usbDescrCopy (pBfr, &langDescr, length, pActLen);
  455. break;
  456.     case ID_STR_MFG:
  457. usbDescrStrCopy (pBfr, pStrMfg, length, pActLen);
  458. break;
  459.     case ID_STR_PROD:
  460. usbDescrStrCopy (pBfr, pStrProd, length, pActLen);
  461. break;
  462.     default:
  463. return ERROR;
  464.     }
  465. break;
  466.     default:
  467. return ERROR;
  468.     }
  469. }
  470.     else
  471. {
  472. return ERROR;
  473. }
  474.     return OK;
  475.     }
  476. /***************************************************************************
  477. *
  478. * interfaceGet - invoked by usbTargLib for GET_INTERFACE request
  479. *
  480. * RETURNS: OK, or ERROR if unable to return interface setting
  481. */
  482. LOCAL STATUS interfaceGet
  483.     (
  484.     pVOID param,
  485.     USB_TARG_CHANNEL targChannel,
  486.     UINT16 interfaceIndex,
  487.     pUINT8 pAlternateSetting
  488.     )
  489.     {
  490.     *pAlternateSetting = curAlternateSetting;
  491.     return OK;
  492.     }
  493. /***************************************************************************
  494. *
  495. * interfaceSet - invoked by usbTargLib for SET_INTERFACE request
  496. *
  497. * RETURNS: OK, or ERROR if unable to set specified interface
  498. */
  499. LOCAL STATUS interfaceSet
  500.     (
  501.     pVOID param,
  502.     USB_TARG_CHANNEL targChannel,
  503.     UINT16 interfaceIndex,
  504.     UINT8 alternateSetting
  505.     )
  506.     {
  507.     curAlternateSetting = alternateSetting;
  508.     return OK;
  509.     }
  510. /***************************************************************************
  511. *
  512. * vendorSpecific - invoked by usbTargLib for VENDOR_SPECIFIC request
  513. *
  514. * RETURNS: OK, or ERROR if unable to process vendor-specific request
  515. */
  516. LOCAL STATUS vendorSpecific
  517.     (
  518.     pVOID param,
  519.     USB_TARG_CHANNEL targChannel,
  520.     UINT8 requestType,
  521.     UINT8 request,
  522.     UINT16 value,
  523.     UINT16 index,
  524.     UINT16 length
  525.     )
  526.     {
  527.     if (requestType == (USB_RT_HOST_TO_DEV | USB_RT_CLASS | USB_RT_INTERFACE))
  528. {
  529. switch (request)
  530.     {
  531.     case USB_REQ_HID_SET_PROTOCOL:
  532.     case USB_REQ_HID_SET_IDLE:
  533. /* This emulator simply acknowledges these HID requests...no
  534.  * processing is required. 
  535.  */
  536. usbTargControlResponseSend (targChannel, 0, NULL);
  537. return OK;
  538.     case USB_REQ_HID_SET_REPORT:
  539. /* This eumulator does not support LED settings.  However, this
  540.  * does give us an opportunity to test usbTargPipeStatusSet().
  541.  */
  542. usbTargPipeStatusSet (targChannel, NULL, TCD_ENDPOINT_STALL);
  543. return ERROR;
  544.     default:
  545. break;
  546.     }
  547. }
  548.     return ERROR;
  549.     }
  550. /* End of file. */