Changeset 60417 in vbox for trunk/src/VBox/ValidationKit/utils/usb/UsbTestService.cpp
- Timestamp:
- Apr 11, 2016 10:37:04 AM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 106503
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/usb/UsbTestService.cpp
r60287 r60417 55 55 #include <iprt/thread.h> 56 56 57 #include "UsbTestServiceCfg.h" 57 58 #include "UsbTestServiceInternal.h" 58 #include "UsbTestService Cfg.h"59 #include "UsbTestServiceGadget.h" 59 60 60 61 … … 63 64 * Structures and Typedefs * 64 65 *********************************************************************************************************************************/ 66 67 #define UTS_USBIP_PORT_FIRST 3240 68 #define UTS_USBIP_PORT_LAST 3340 65 69 66 70 /** … … 94 98 /** Client hostname. */ 95 99 char *pszHostname; 100 /** Gadget host handle. */ 101 UTSGADGETHOST hGadgetHost; 102 /** Handle fo the current configured gadget. */ 103 UTSGADGET hGadget; 96 104 } UTSCLIENT; 97 105 /** Pointer to a UTS client instance. */ … … 115 123 /** The select transport layer. */ 116 124 static PCUTSTRANSPORT g_pTransport; 117 /** The scratchpath. */125 /** The config path. */ 118 126 static char g_szCfgPath[RTPATH_MAX]; 119 127 /** The scratch path. */ … … 154 162 /** List of new clients waiting to be picked up by the client worker thread. */ 155 163 static RTLISTANCHOR g_LstClientsNew; 164 /** First USB/IP port we can use. */ 165 static uint16_t g_uUsbIpPortFirst = UTS_USBIP_PORT_FIRST; 166 /** Last USB/IP port we can use. */ 167 static uint16_t g_uUsbIpPortLast = UTS_USBIP_PORT_LAST; 168 /** Next free port. */ 169 static uint16_t g_uUsbIpPortNext = UTS_USBIP_PORT_FIRST; 156 170 157 171 … … 527 541 528 542 /** 543 * Creates the configuration from the given GADGET CREATE packet. 544 * 545 * @returns IPRT status code. 546 * @param pReq The gadget create request. 547 * @param paCfg The array of configuration items. 548 */ 549 static int utsDoGadgetCreateFillCfg(PUTSPKTREQGDGTCTOR pReq, PUTSGADGETCFGITEM paCfg) 550 { 551 return VERR_NOT_IMPLEMENTED; 552 } 553 554 /** 529 555 * Verifies and acknowledges a "BYE" request. 530 556 * … … 553 579 static int utsDoHowdy(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr) 554 580 { 581 int rc = VINF_SUCCESS; 582 555 583 if (pPktHdr->cb != sizeof(UTSPKTREQHOWDY)) 556 584 return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQHOWDY)); … … 576 604 return utsReplyRC(pClient, pPktHdr, VERR_NO_MEMORY, "Failed to alllocate memory for the hostname string"); 577 605 578 int rc = utsReplyAck(pClient, pPktHdr); 606 if (pReq->fUsbConn & UTSPKT_HOWDY_CONN_F_PHYSICAL) 607 return utsReplyRC(pClient, pPktHdr, VERR_NOT_SUPPORTED, "Physical connections are not yet supported"); 608 609 if (pReq->fUsbConn & UTSPKT_HOWDY_CONN_F_USBIP) 610 { 611 /* Set up the USB/IP server, find an unused port we can start the server on. */ 612 UTSGADGETCFGITEM aCfg[2]; 613 614 uint16_t uPort = g_uUsbIpPortNext; 615 616 if (g_uUsbIpPortNext == g_uUsbIpPortLast) 617 g_uUsbIpPortNext = g_uUsbIpPortFirst; 618 else 619 g_uUsbIpPortNext++; 620 621 aCfg[0].pszKey = "UsbIp/Port"; 622 aCfg[0].Val.enmType = UTSGADGETCFGTYPE_UINT16; 623 aCfg[0].Val.u.u16 = uPort; 624 aCfg[1].pszKey = NULL; 625 626 rc = utsGadgetHostCreate(UTSGADGETHOSTTYPE_USBIP, &aCfg[0], &pClient->hGadgetHost); 627 if (RT_SUCCESS(rc)) 628 { 629 /* Send the reply with the configured USB/IP port. */ 630 UTSPKTREPHOWDY Rep; 631 632 RT_ZERO(Rep); 633 634 Rep.uVersion = UTS_PROTOCOL_VS; 635 Rep.fUsbConn = UTSPKT_HOWDY_CONN_F_USBIP; 636 Rep.uUsbIpPort = uPort; 637 Rep.cUsbIpDevices = 1; 638 Rep.cPhysicalDevices = 0; 639 640 rc = utsReplyInternal(pClient, &Rep.Sts, "ACK ", sizeof(Rep) - sizeof(UTSPKTSTS)); 641 if (RT_SUCCESS(rc)) 642 { 643 g_pTransport->pfnNotifyHowdy(pClient->pTransportClient); 644 pClient->enmState = UTSCLIENTSTATE_READY; 645 RTDirRemoveRecursive(g_szScratchPath, RTDIRRMREC_F_CONTENT_ONLY); 646 } 647 } 648 else 649 return utsReplyRC(pClient, pPktHdr, rc, "Creating the USB/IP gadget host failed"); 650 } 651 else 652 return utsReplyRC(pClient, pPktHdr, VERR_INVALID_PARAMETER, "No access method requested"); 653 654 return rc; 655 } 656 657 /** 658 * Verifies and processes a "GADGET CREATE" request. 659 * 660 * @returns IPRT status code. 661 * @param pClient The UTS client structure. 662 * @param pPktHdr The gadget create packet. 663 */ 664 static int utsDoGadgetCreate(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr) 665 { 666 int rc = VINF_SUCCESS; 667 668 if (pPktHdr->cb < sizeof(UTSPKTREQGDGTCTOR)) 669 return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQGDGTCTOR)); 670 671 if ( pClient->enmState != UTSCLIENTSTATE_READY 672 || pClient->hGadgetHost == NIL_UTSGADGETHOST) 673 return utsReplyInvalidState(pClient, pPktHdr); 674 675 PUTSPKTREQGDGTCTOR pReq = (PUTSPKTREQGDGTCTOR)pPktHdr; 676 677 if (pReq->u32GdgtType != UTSPKT_GDGT_CREATE_TYPE_TEST) 678 return utsReplyRC(pClient, pPktHdr, VERR_INVALID_PARAMETER, "The given gadget type is not supported"); 679 680 if (pReq->u32GdgtAccess != UTSPKT_GDGT_CREATE_ACCESS_USBIP) 681 return utsReplyRC(pClient, pPktHdr, VERR_INVALID_PARAMETER, "The given gadget access method is not supported"); 682 683 PUTSGADGETCFGITEM paCfg = NULL; 684 if (pReq->u32CfgItems > 0) 685 { 686 paCfg = (PUTSGADGETCFGITEM)RTMemAllocZ((pReq->u32CfgItems + 1) * sizeof(UTSGADGETCFGITEM)); 687 if (RT_UNLIKELY(!paCfg)) 688 return utsReplyRC(pClient, pPktHdr, VERR_NO_MEMORY, "Failed to allocate memory for configration items"); 689 690 rc = utsDoGadgetCreateFillCfg(pReq, paCfg); 691 if (RT_FAILURE(rc)) 692 { 693 RTMemFree(paCfg); 694 return utsReplyRC(pClient, pPktHdr, rc, "Failed to parse configuration"); 695 } 696 } 697 698 rc = utsGadgetCreate(pClient->hGadgetHost, UTSGADGETCLASS_TEST, paCfg, &pClient->hGadget); 579 699 if (RT_SUCCESS(rc)) 580 700 { 581 g_pTransport->pfnNotifyHowdy(pClient->pTransportClient); 582 RTDirRemoveRecursive(g_szScratchPath, RTDIRRMREC_F_CONTENT_ONLY); 701 UTSPKTREPGDGTCTOR Rep; 702 RT_ZERO(Rep); 703 704 Rep.idGadget = 0; 705 rc = utsReplyInternal(pClient, &Rep.Sts, "ACK ", sizeof(Rep) - sizeof(UTSPKTSTS)); 583 706 } 707 else 708 rc = utsReplyRC(pClient, pPktHdr, rc, "Failed to create gadget with %Rrc\n", rc); 709 710 return rc; 711 } 712 713 /** 714 * Verifies and processes a "GADGET DESTROY" request. 715 * 716 * @returns IPRT status code. 717 * @param pClient The UTS client structure. 718 * @param pPktHdr The gadget destroy packet. 719 */ 720 static int utsDoGadgetDestroy(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr) 721 { 722 if (pPktHdr->cb != sizeof(UTSPKTREQGDGTDTOR)) 723 return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQGDGTDTOR)); 724 725 if ( pClient->enmState != UTSCLIENTSTATE_READY 726 || pClient->hGadgetHost == NIL_UTSGADGETHOST) 727 return utsReplyInvalidState(pClient, pPktHdr); 728 729 PUTSPKTREQGDGTDTOR pReq = (PUTSPKTREQGDGTDTOR)pPktHdr; 730 731 if (pReq->idGadget != 0) 732 return utsReplyRC(pClient, pPktHdr, VERR_INVALID_HANDLE, "The given gadget handle is invalid"); 733 if (pClient->hGadget == NIL_UTSGADGET) 734 return utsReplyRC(pClient, pPktHdr, VERR_INVALID_STATE, "The gadget is not set up"); 735 736 utsGadgetRelease(pClient->hGadget); 737 pClient->hGadget = NIL_UTSGADGET; 738 739 return utsReplyAck(pClient, pPktHdr); 740 } 741 742 /** 743 * Verifies and processes a "GADGET CONNECT" request. 744 * 745 * @returns IPRT status code. 746 * @param pClient The UTS client structure. 747 * @param pPktHdr The gadget connect packet. 748 */ 749 static int utsDoGadgetConnect(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr) 750 { 751 if (pPktHdr->cb != sizeof(UTSPKTREQGDGTCNCT)) 752 return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQGDGTCNCT)); 753 754 if ( pClient->enmState != UTSCLIENTSTATE_READY 755 || pClient->hGadgetHost == NIL_UTSGADGETHOST) 756 return utsReplyInvalidState(pClient, pPktHdr); 757 758 PUTSPKTREQGDGTCNCT pReq = (PUTSPKTREQGDGTCNCT)pPktHdr; 759 760 if (pReq->idGadget != 0) 761 return utsReplyRC(pClient, pPktHdr, VERR_INVALID_HANDLE, "The given gadget handle is invalid"); 762 if (pClient->hGadget == NIL_UTSGADGET) 763 return utsReplyRC(pClient, pPktHdr, VERR_INVALID_STATE, "The gadget is not set up"); 764 765 int rc = utsGadgetConnect(pClient->hGadget); 766 if (RT_SUCCESS(rc)) 767 rc = utsReplyAck(pClient, pPktHdr); 768 else 769 rc = utsReplyRC(pClient, pPktHdr, rc, "Failed to connect the gadget"); 770 771 return rc; 772 } 773 774 /** 775 * Verifies and processes a "GADGET DISCONNECT" request. 776 * 777 * @returns IPRT status code. 778 * @param pClient The UTS client structure. 779 * @param pPktHdr The gadget disconnect packet. 780 */ 781 static int utsDoGadgetDisconnect(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr) 782 { 783 if (pPktHdr->cb != sizeof(UTSPKTREQGDGTDCNT)) 784 return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQGDGTDCNT)); 785 786 if ( pClient->enmState != UTSCLIENTSTATE_READY 787 || pClient->hGadgetHost == NIL_UTSGADGETHOST) 788 return utsReplyInvalidState(pClient, pPktHdr); 789 790 PUTSPKTREQGDGTDCNT pReq = (PUTSPKTREQGDGTDCNT)pPktHdr; 791 792 if (pReq->idGadget != 0) 793 return utsReplyRC(pClient, pPktHdr, VERR_INVALID_HANDLE, "The given gadget handle is invalid"); 794 if (pClient->hGadget == NIL_UTSGADGET) 795 return utsReplyRC(pClient, pPktHdr, VERR_INVALID_STATE, "The gadget is not set up"); 796 797 int rc = utsGadgetDisconnect(pClient->hGadget); 798 if (RT_SUCCESS(rc)) 799 rc = utsReplyAck(pClient, pPktHdr); 800 else 801 rc = utsReplyRC(pClient, pPktHdr, rc, "Failed to disconnect the gadget"); 802 584 803 return rc; 585 804 } … … 609 828 else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_BYE)) 610 829 rc = utsDoBye(pClient, pPktHdr); 830 /* Gadget API. */ 831 else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_GADGET_CREATE)) 832 rc = utsDoGadgetCreate(pClient, pPktHdr); 833 else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_GADGET_DESTROY)) 834 rc = utsDoGadgetCreate(pClient, pPktHdr); 835 else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_GADGET_CONNECT)) 836 rc = utsDoGadgetConnect(pClient, pPktHdr); 837 else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_GADGET_DISCONNECT)) 838 rc = utsDoGadgetDisconnect(pClient, pPktHdr); 611 839 /* Misc: */ 612 840 else … … 628 856 if (pClient->pszHostname) 629 857 RTStrFree(pClient->pszHostname); 858 if (pClient->hGadget != NIL_UTSGADGET) 859 utsGadgetRelease(pClient->hGadget); 860 if (pClient->hGadgetHost != NIL_UTSGADGETHOST) 861 utsGadgetHostRelease(pClient->hGadgetHost); 630 862 RTMemFree(pClient); 631 863 } … … 768 1000 pClient->enmState = UTSCLIENTSTATE_INITIALISING; 769 1001 pClient->pTransportClient = pTransportClient; 1002 pClient->pszHostname = NULL; 1003 pClient->hGadgetHost = NIL_UTSGADGETHOST; 1004 pClient->hGadget = NIL_UTSGADGET; 770 1005 } 771 1006 else
Note:
See TracChangeset
for help on using the changeset viewer.