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

VxWorks

开发平台:

C/C++

  1. /* usbTargPrnLib.c - USB printer 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,30aug99,rcb  First.
  8. */
  9. /*
  10. DESCRIPTION
  11. This module contains code to exercise the usbTargLib by emulating a rudimentary
  12. USB printer.  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. usbTargPrnCallbackInfo().  It is not necessary to initialize the usbTartPrnLib 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, usbTargPrnBfrInfo(), which allows a test
  22. application to retrieve the current status of the bulk output buffer.
  23. */
  24. /* includes */
  25. #include "usb/usbPlatform.h"
  26. #include "string.h"
  27. #include "usb/usb.h"
  28. #include "usb/usbPrinter.h"     /* USB PRINTER definitions */
  29. #include "usb/usbDescrCopyLib.h"     /* USB utility functions */
  30. #include "usb/target/usbTargLib.h"     /* USB target functions */
  31. #include "drv/usb/target/usbTargPrnLib.h"   /* our API */
  32. /* defines */
  33. /* Define USE_DMA_ENDPOINT to direct printer data to the Philips PDIUSBD12
  34.  * "main" endpoint (#2) which uses DMA.  Un-define USE_DMA_ENDPOINT to direct
  35.  * printer data to the generic endpoint (#1) which uses programmed-IO.
  36.  */
  37. #define USE_DMA_ENDPOINT
  38. /* string identifiers */
  39. #define UNICODE_ENGLISH     0x409
  40. #define ID_STR_MFG     1
  41. #define ID_STR_MFG_VAL     "Wind River Systems"
  42. #define ID_STR_PROD     2
  43. #define ID_STR_PROD_VAL     "USB printer emulator"
  44. /* printer "capabilities" string */
  45. #define PRN_CAPS    "mfg:WRS;model=emulator;"
  46. /* printer device */
  47. #define PRN_USB_VERSION  0x0100
  48. #define PRN_NUM_CONFIG 1
  49. /* printer configuration */
  50. #define PRN_CONFIG_VALUE 1
  51. #define PRN_NUM_INTERFACES 1
  52. /* printer interface */
  53. #define PRN_INTERFACE_NUM 0
  54. #define PRN_INTERFACE_ALT_SETTING 1
  55. #define PRN_NUM_ENDPOINTS 1
  56. /* printer BULK OUT endpoint */
  57. #ifdef USE_DMA_ENDPOINT
  58. #define PRN_BULK_OUT_ENDPOINT_ID 4 /* PDIUSBD12 "main out" endpoint */
  59. #define PRN_BULK_OUT_ENDPOINT_NUM 0x02
  60. #else
  61. #define PRN_BULK_OUT_ENDPOINT_ID 2 /* PDIUSBD12 "generic out" endpoint */
  62. #define PRN_BULK_OUT_ENDPOINT_NUM 0x01
  63. #endif
  64. #define BULK_BFR_LEN 4096
  65. /* typedefs */
  66. /* forward declarations */
  67. LOCAL STATUS mngmtFunc
  68.     (
  69.     pVOID param,
  70.     USB_TARG_CHANNEL targChannel,
  71.     UINT16 mngmtCode
  72.     );
  73. LOCAL STATUS configurationGet
  74.     (
  75.     pVOID param,
  76.     USB_TARG_CHANNEL targChannel,
  77.     pUINT8 pConfiguration
  78.     );
  79. LOCAL STATUS configurationSet
  80.     (
  81.     pVOID param,
  82.     USB_TARG_CHANNEL targChannel,
  83.     UINT8 configuration
  84.     );
  85. LOCAL STATUS descriptorGet
  86.     (
  87.     pVOID param,
  88.     USB_TARG_CHANNEL targChannel,
  89.     UINT8 requestType,
  90.     UINT8 descriptorType,
  91.     UINT8 descriptorIndex,
  92.     UINT16 languageId,
  93.     UINT16 length,
  94.     pUINT8 pBfr,
  95.     pUINT16 pActLen
  96.     );
  97. LOCAL STATUS interfaceGet
  98.     (
  99.     pVOID param,
  100.     USB_TARG_CHANNEL targChannel,
  101.     UINT16 interfaceIndex,
  102.     pUINT8 pAlternateSetting
  103.     );
  104. LOCAL STATUS interfaceSet
  105.     (
  106.     pVOID param,
  107.     USB_TARG_CHANNEL targChannel,
  108.     UINT16 interfaceIndex,
  109.     UINT8 alternateSetting
  110.     );
  111. LOCAL STATUS vendorSpecific
  112.     (
  113.     pVOID param,
  114.     USB_TARG_CHANNEL targChannel,
  115.     UINT8 requestType,
  116.     UINT8 request,
  117.     UINT16 value,
  118.     UINT16 index,
  119.     UINT16 length
  120.     );
  121. /* locals */
  122. LOCAL USB_TARG_CALLBACK_TABLE usbTargPrnCallbackTable =
  123.     {
  124.     mngmtFunc, /* mngmtFunc */
  125.     NULL, /* featureClear */
  126.     NULL, /* featureSet */
  127.     configurationGet, /* configurationGet */
  128.     configurationSet, /* configurationSet */
  129.     descriptorGet, /* descriptorGet */
  130.     NULL, /* descriptorSet */
  131.     interfaceGet, /* interfaceGet */
  132.     interfaceSet, /* interfaceSet */
  133.     NULL, /* statusGet */
  134.     NULL, /* addressSet */
  135.     NULL, /* synchFrameGet */
  136.     vendorSpecific, /* vendorSpecific */
  137.     };
  138. LOCAL USB_TARG_CHANNEL channel;
  139. LOCAL UINT16 numEndpoints;
  140. LOCAL pUSB_TARG_ENDPOINT_INFO pEndpoints;
  141. LOCAL UINT8 curConfiguration;
  142. LOCAL UINT8 curAlternateSetting;
  143. LOCAL USB_TARG_PIPE bulkPipeHandle;
  144. LOCAL USB_ERP bulkErp;
  145. LOCAL BOOL bulkInUse;
  146. LOCAL pUINT8 bulkBfr;
  147. LOCAL BOOL bulkBfrValid;
  148. LOCAL char capsString [] = PRN_CAPS;
  149. LOCAL USB_PRINTER_PORT_STATUS portStatus = 
  150.     {USB_PRN_STS_SELECTED | USB_PRN_STS_NOT_ERROR};
  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 (PRN_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.     PRN_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.     PRN_NUM_INTERFACES,      /* bNumInterfaces */
  181.     PRN_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.     PRN_INTERFACE_NUM,     /* bInterfaceNumber */
  191.     PRN_INTERFACE_ALT_SETTING,     /* bAlternateSetting */
  192.     PRN_NUM_ENDPOINTS,     /* bNumEndpoints */
  193.     USB_CLASS_PRINTER,     /* bInterfaceClass */
  194.     USB_SUBCLASS_PRINTER,     /* bInterfaceSubClass */
  195.     USB_PROTOCOL_PRINTER_UNIDIR,    /* bInterfaceProtocol */
  196.     0     /* iInterface */
  197.     };
  198. LOCAL USB_ENDPOINT_DESCR epDescr =
  199.     {
  200.     USB_ENDPOINT_DESCR_LEN,     /* bLength */
  201.     USB_DESCR_ENDPOINT,      /* bDescriptorType */
  202.     PRN_BULK_OUT_ENDPOINT_NUM,     /* bEndpointAddress */
  203.     USB_ATTR_BULK,     /* bmAttributes */
  204.     USB_MIN_CTRL_PACKET_SIZE,     /* maxPacketSize */
  205.     0     /* bInterval */
  206.     };
  207. /* functions */
  208. /***************************************************************************
  209. *
  210. * bulkErpCallback - called when report ERP terminates
  211. *
  212. * RETURNS: N/A
  213. */
  214. LOCAL VOID bulkErpCallback
  215.     (
  216.     pVOID p /* pointer to ERP */
  217.     )
  218.     {
  219.     bulkInUse = FALSE;
  220.     bulkBfrValid = TRUE;
  221.     }
  222. /***************************************************************************
  223. *
  224. * initBulkOutErp - listen for output printer data
  225. *
  226. * RETURNS: OK, or ERROR if unable to submit ERP.
  227. */
  228. LOCAL STATUS initBulkOutErp (void)
  229.     {
  230.     if (bulkBfr == NULL)
  231. return ERROR;
  232.     if (bulkInUse)
  233. return OK;
  234.     /* Initialize bulk ERP */
  235.     memset (&bulkErp, 0, sizeof (bulkErp));
  236.     bulkErp.erpLen = sizeof (bulkErp);
  237.     bulkErp.userCallback = bulkErpCallback;
  238.     bulkErp.bfrCount = 1;
  239.     bulkErp.bfrList [0].pid = USB_PID_OUT;
  240.     bulkErp.bfrList [0].pBfr = bulkBfr;
  241.     bulkErp.bfrList [0].bfrLen = BULK_BFR_LEN;
  242.     bulkInUse = TRUE;
  243.     bulkBfrValid = FALSE;
  244.     if (usbTargTransfer (bulkPipeHandle, &bulkErp) != OK)
  245. {
  246. bulkInUse = FALSE;
  247. return ERROR;
  248. }
  249.     return OK;
  250.     }
  251. /***************************************************************************
  252. *
  253. * usbTargPrnCallbackInfo - returns usbTargPrnLib callback table
  254. *
  255. * RETURNS: N/A
  256. */
  257. VOID usbTargPrnCallbackInfo
  258.     (
  259.     pUSB_TARG_CALLBACK_TABLE *ppCallbacks,
  260.     pVOID *pCallbackParam
  261.     )
  262.     {
  263.     if (ppCallbacks != NULL)
  264. *ppCallbacks = &usbTargPrnCallbackTable;
  265.     if (pCallbackParam != NULL)
  266. *pCallbackParam = NULL;
  267.     }
  268. /***************************************************************************
  269. *
  270. * usbTargPrnDataInfo - returns buffer status/info
  271. *
  272. * RETURNS: OK if buffer has valid data, else ERROR
  273. */
  274. STATUS usbTargPrnDataInfo
  275.     (
  276.     pUINT8 *ppBfr,
  277.     pUINT16 pActLen
  278.     )
  279.     {
  280.     if (!bulkBfrValid)
  281. return ERROR;
  282.     if (ppBfr != NULL)
  283. *ppBfr = bulkBfr;
  284.     if (pActLen != NULL)
  285. *pActLen = bulkErp.bfrList [0].actLen;
  286.     return OK;
  287.     }
  288. /***************************************************************************
  289. *
  290. * usbTargPrnDataRestart - restarts listening ERP
  291. *
  292. * RETURNS: OK, or ERROR if unable to re-initiate ERP
  293. */
  294. STATUS usbTargPrnDataRestart (void)
  295.     {
  296.     return initBulkOutErp ();
  297.     }
  298. /***************************************************************************
  299. *
  300. * mngmtFunc - invoked by usbTargLib for connection management events
  301. *
  302. * RETURNS: OK if able to handle event, or ERROR if unable to handle event
  303. */
  304. LOCAL STATUS mngmtFunc
  305.     (
  306.     pVOID param,
  307.     USB_TARG_CHANNEL targChannel,
  308.     UINT16 mngmtCode     /* management code */
  309.     )
  310.     {
  311.     switch (mngmtCode)
  312. {
  313. case TCD_MNGMT_ATTACH:
  314.     /* Initialize global data */
  315.     channel = targChannel;
  316.     usbTargEndpointInfoGet (targChannel, &numEndpoints, &pEndpoints);
  317.     curConfiguration = 0;
  318.     curAlternateSetting = 0;
  319.     bulkPipeHandle = NULL;
  320.     /* Initialize control pipe maxPacketSize. */
  321.     devDescr.maxPacketSize0 = pEndpoints [0].maxPacketSize;
  322.     /* Initialize bulk endpoint max packet size. */
  323.     epDescr.maxPacketSize = 
  324. pEndpoints [PRN_BULK_OUT_ENDPOINT_ID].bulkOutMaxPacketSize;
  325.     /* Allocate buffer */
  326.     if ((bulkBfr = OSS_MALLOC (BULK_BFR_LEN)) == NULL)
  327. return ERROR;
  328.     break;
  329. case TCD_MNGMT_DETACH:
  330.     /* De-allocate buffer */
  331.     if (bulkBfr != NULL)
  332. {
  333. OSS_FREE (bulkBfr);
  334. bulkBfr = NULL;
  335. }
  336.     break;
  337. case TCD_MNGMT_BUS_RESET:
  338. case TCD_MNGMT_VBUS_LOST:
  339.     /* revert to power-ON configuration */
  340.     configurationSet (param, targChannel, 0);
  341.     break;     
  342. default:
  343.     break;
  344. }
  345.     return OK;
  346.     }
  347. /***************************************************************************
  348. *
  349. * configurationGet - invoked by usbTargLib for GET_CONFIGURATION request
  350. *
  351. * RETURNS: OK, or ERROR if unable to return configuration setting
  352. */
  353. LOCAL STATUS configurationGet
  354.     (
  355.     pVOID param,
  356.     USB_TARG_CHANNEL targChannel,
  357.     pUINT8 pConfiguration
  358.     )
  359.     {
  360.     *pConfiguration = curConfiguration;
  361.     return OK;
  362.     }
  363. /***************************************************************************
  364. *
  365. * configurationSet - invoked by usbTargLib for SET_CONFIGURATION request
  366. *
  367. * RETURNS: OK, or ERROR if unable to set specified configuration
  368. */
  369. LOCAL STATUS configurationSet
  370.     (
  371.     pVOID param,
  372.     USB_TARG_CHANNEL targChannel,
  373.     UINT8 configuration
  374.     )
  375.     {
  376.     if (configuration > PRN_CONFIG_VALUE)
  377. return ERROR;
  378.     if ((curConfiguration = configuration) == PRN_CONFIG_VALUE)
  379. {
  380. /* Enable the interrupt status pipe if not already enabled. */
  381. if (bulkPipeHandle == NULL)
  382.     {
  383.     /* Create a pipe */
  384.     if (usbTargPipeCreate (targChannel, PRN_BULK_OUT_ENDPOINT_ID, 0,
  385. PRN_BULK_OUT_ENDPOINT_NUM, configuration, PRN_INTERFACE_NUM, 
  386. USB_XFRTYPE_BULK, USB_DIR_OUT, &bulkPipeHandle) != OK)
  387. return ERROR;
  388.     /* Initialize ERP to listen for data */
  389.     initBulkOutErp ();
  390.     }
  391. }
  392.     else
  393. {
  394. /* Disable the interrupt status pipe if it's enabled */
  395. if (bulkPipeHandle != NULL)
  396.     {
  397.     usbTargPipeDestroy (bulkPipeHandle);
  398.     bulkPipeHandle = 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.     UINT8 bfr [USB_MAX_DESCR_LEN];
  528.     pUSB_PRINTER_CAPABILITIES pCaps = (pUSB_PRINTER_CAPABILITIES) bfr;
  529.     UINT16 capsLen = strlen (capsString) + 2;
  530.     if (requestType == (USB_RT_DEV_TO_HOST | USB_RT_CLASS | USB_RT_INTERFACE))
  531. {
  532. switch (request)
  533.     {
  534.     case USB_REQ_PRN_GET_DEVICE_ID:
  535. /* Send the IEEE-1284-style "device id" string. */
  536. pCaps->length = TO_BIGW (capsLen);
  537. memcpy (pCaps->caps, capsString, strlen (capsString));
  538. usbTargControlResponseSend (targChannel, capsLen, (pUINT8) pCaps);
  539. return OK;
  540.     case USB_REQ_PRN_GET_PORT_STATUS:
  541. /* This emulator simply acknowledges these HID requests...no
  542.  * processing is required. 
  543.  */
  544. usbTargControlResponseSend (targChannel, 
  545.     sizeof (portStatus), (pUINT8) &portStatus);
  546. return OK;
  547.     default:
  548. break;
  549.     }
  550. }
  551.     else if (requestType == (USB_RT_HOST_TO_DEV | USB_RT_CLASS | USB_RT_OTHER))
  552. {
  553. switch (request)
  554.     {
  555.     case USB_REQ_PRN_SOFT_RESET:
  556. /* We accept the SOFT_RESET and return OK. */
  557. return OK;
  558.     default:
  559. break;
  560.     }
  561. }
  562.     return ERROR;
  563.     }
  564. /* End of file. */