Changeset 60429 in vbox
- Timestamp:
- Apr 11, 2016 3:42:41 PM (8 years ago)
- File:
-
- 1 copied
-
trunk/src/VBox/ValidationKit/tests/usb/usbgadget2.py (copied) (copied from trunk/src/VBox/ValidationKit/testdriver/txsclient.py ) (27 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/tests/usb/usbgadget2.py
r60375 r60429 4 4 5 5 """ 6 Test eXecution Service Client.6 UTS (USB Test Service) client. 7 7 """ 8 8 __copyright__ = \ 9 9 """ 10 Copyright (C) 2010-201 5Oracle Corporation10 Copyright (C) 2010-2016 Oracle Corporation 11 11 12 12 This file is part of VirtualBox Open Source Edition (OSE), as … … 47 47 from testdriver.base import TdTaskBase; 48 48 49 ## @name USB gadget impersonation string constants. 50 ## @{ 51 g_ksGadgetImpersonationInvalid = 'Invalid'; 52 g_ksGadgetImpersonationTest = 'Test'; 53 g_ksGadgetImpersonationMsd = 'Msd'; 54 g_ksGadgetImpersonationWebcam = 'Webcam'; 55 g_ksGadgetImpersonationEther = 'Ether'; 56 ## @} 57 58 ## @name USB gadget type used in the UTS protocol. 59 ## @{ 60 g_kiGadgetTypeTest = 1; 61 ## @} 62 63 ## @name USB gadget access methods used in the UTS protocol. 64 ## @{ 65 g_kiGadgetAccessUsbIp = 1; 66 ## @} 67 49 68 # 50 # Helpers for decoding data received from the TXS.69 # Helpers for decoding data received from the UTS. 51 70 # These are used both the Session and Transport classes. 52 71 # … … 112 131 113 132 # 114 # Helper for encoding data sent to the TXS.133 # Helper for encoding data sent to the UTS. 115 134 # 116 135 … … 123 142 (u32 / 16777216) % 256) ); 124 143 125 144 def u16ToByteArray(u16): 145 """Encodes the u16 value as a little endian byte (B) array.""" 146 return array.array('B', \ 147 ( u16 % 256, \ 148 (u16 / 256) % 256) ); 149 150 def u8ToByteArray(u8): 151 """Encodes the u8 value as a little endian byte (B) array.""" 152 return array.array('B', (u8 % 256); 126 153 127 154 class TransportBase(object): … … 153 180 def connect(self, cMsTimeout): 154 181 """ 155 Quietly attempts to connect to the TXS.182 Quietly attempts to connect to the UTS. 156 183 157 184 Returns True on success. … … 166 193 def disconnect(self, fQuiet = False): 167 194 """ 168 Disconnect from the TXS.195 Disconnect from the UTS. 169 196 170 197 Returns True. … … 177 204 def sendBytes(self, abBuf, cMsTimeout): 178 205 """ 179 Sends the bytes in the buffer abBuf to the TXS.206 Sends the bytes in the buffer abBuf to the UTS. 180 207 181 208 Returns True on success. … … 191 218 def recvBytes(self, cb, cMsTimeout, fNoDataOk): 192 219 """ 193 Receive cb number of bytes from the TXS.220 Receive cb number of bytes from the UTS. 194 221 195 222 Returns the bytes (array('B')) on success. … … 275 302 def recvMsg(self, cMsTimeout, fNoDataOk = False): 276 303 """ 277 Receives a message from the TXS.304 Receives a message from the UTS. 278 305 279 306 Returns the message three-tuple: length, opcode, payload. … … 376 403 class Session(TdTaskBase): 377 404 """ 378 A Test eXecution Service (TXS) client session.405 A USB Test Service (UTS) client session. 379 406 """ 380 407 381 408 def __init__(self, oTransport, cMsTimeout, cMsIdleFudge, fTryConnect = False): 382 409 """ 383 Construct a TXS session.384 385 This starts by connecting to the TXS and will enter the signalled state410 Construct a UTS session. 411 412 This starts by connecting to the UTS and will enter the signalled state 386 413 when connected or the timeout has been reached. 387 414 """ … … 431 458 """ 432 459 if not self.cancelTask(): 433 reporter.maybeErr(not fIgnoreErrors, ' txsclient.Session.startTask: failed to cancel previous task.');460 reporter.maybeErr(not fIgnoreErrors, 'utsclient.Session.startTask: failed to cancel previous task.'); 434 461 return False; 435 462 … … 438 465 if self.sStatus != "": 439 466 self.unlockTask(); 440 reporter.maybeErr(not fIgnoreErrors, ' txsclient.Session.startTask: race.');467 reporter.maybeErr(not fIgnoreErrors, 'utsclient.Session.startTask: race.'); 441 468 return False; 442 469 self.sStatus = "setup"; … … 450 477 self.fnTask = fnTask; 451 478 self.aTaskArgs = aArgs; 452 self.oThread = threading.Thread(target=self.taskThread, args=(), name=(' TXS-%s' % (sStatus)));479 self.oThread = threading.Thread(target=self.taskThread, args=(), name=('UTS-%s' % (sStatus))); 453 480 self.oThread.setDaemon(True); 454 481 self.msStart = base.timestampMilli(); … … 478 505 return False; 479 506 480 reporter.log(' txsclient: cancelling "%s"...' % (self.sStatus));507 reporter.log('utsclient: cancelling "%s"...' % (self.sStatus)); 481 508 if self.sStatus == 'connecting': 482 509 self.oTransport.cancelConnect(); … … 561 588 def recvAck(self, fNoDataOk = False): 562 589 """ 563 Receives an ACK or error response from the TXS.590 Receives an ACK or error response from the UTS. 564 591 565 592 Returns True on success. … … 580 607 Wrapper for recvAck and logging. 581 608 Returns True on success (ACK). 582 Returns False on time, transport error and errors signalled by TXS.609 Returns False on time, transport error and errors signalled by UTS. 583 610 """ 584 611 rc = self.recvAck(fNoDataOk); … … 593 620 def recvTrueFalse(self, sCommand): 594 621 """ 595 Receives a TRUE/FALSE response from the TXS.622 Receives a TRUE/FALSE response from the UTS. 596 623 Returns True on TRUE, False on FALSE and None on error/other (logged). 597 624 """ … … 644 671 645 672 def taskConnect(self, cMsIdleFudge): 646 """Tries to connect to the TXS"""673 """Tries to connect to the UTS""" 647 674 while not self.isCancelled(): 648 675 reporter.log2('taskConnect: connecting ...'); … … 665 692 666 693 def taskGreet(self, cMsIdleFudge): 667 """Greets the TXS"""694 """Greets the UTS""" 668 695 rc = self.sendMsg("HOWDY", ()); 669 696 if rc is True: … … 678 705 679 706 def taskBye(self): 680 """Says goodbye to the TXS"""707 """Says goodbye to the UTS""" 681 708 rc = self.sendMsg("BYE"); 682 709 if rc is True: … … 685 712 return rc; 686 713 687 def taskUuid(self): 688 """Gets the TXS UUID""" 689 rc = self.sendMsg("UUID"); 690 if rc is True: 691 rc = False; 692 cbMsg, sOpcode, abPayload = self.recvReply(); 693 if cbMsg is not None: 694 sOpcode = sOpcode.strip() 695 if sOpcode == "ACK UUID": 696 sUuid = getSZ(abPayload, 0); 697 if sUuid is not None: 698 sUuid = '{%s}' % (sUuid,) 699 try: 700 _ = uuid.UUID(sUuid); 701 rc = sUuid; 702 except: 703 reporter.errorXcpt('taskUuid got an invalid UUID string %s' % (sUuid,)); 704 else: 705 reporter.maybeErr(self.fErr, 'taskUuid did not get a UUID string.'); 706 else: 707 reporter.maybeErr(self.fErr, 'taskUuid got a bad reply: %s' % (sOpcode,)); 708 else: 709 reporter.maybeErr(self.fErr, 'taskUuid got 3xNone from recvReply.'); 714 # 715 # Gadget tasks. 716 # 717 718 def taskGadgetCreate(self, iGadgetType, iGadgetAccess): 719 """Creates a new gadget on UTS""" 720 fRc = self.senfMsg("GDGTCRT", (iGadgetType, iGadgetAccess, 0)); 721 if fRc is True: 722 fRc = self.recvAckLogged("GDGTCRT"); 710 723 return rc; 711 724 712 # 713 # Process task 714 # pylint: disable=C0111 715 # 716 717 def taskExecEx(self, sExecName, fFlags, asArgs, asAddEnv, oStdIn, oStdOut, oStdErr, oTestPipe, sAsUser): # pylint: disable=R0913,R0914,R0915,C0301 718 # Construct the payload. 719 aoPayload = [long(fFlags), '%s' % (sExecName), long(len(asArgs))]; 720 for sArg in asArgs: 721 aoPayload.append('%s' % (sArg)); 722 aoPayload.append(long(len(asAddEnv))); 723 for sPutEnv in asAddEnv: 724 aoPayload.append('%s' % (sPutEnv)); 725 for o in (oStdIn, oStdOut, oStdErr, oTestPipe): 726 if isinstance(o, basestring): 727 aoPayload.append(o); 728 elif o is not None: 729 aoPayload.append('|'); 730 o.uTxsClientCrc32 = zlib.crc32(''); 731 else: 732 aoPayload.append(''); 733 aoPayload.append('%s' % (sAsUser)); 734 aoPayload.append(long(self.cMsTimeout)); 735 736 # Kick of the EXEC command. 737 rc = self.sendMsg('EXEC', aoPayload) 738 if rc is True: 739 rc = self.recvAckLogged('EXEC'); 740 if rc is True: 741 # Loop till the process completes, feed input to the TXS and 742 # receive output from it. 743 sFailure = ""; 744 msPendingInputReply = None; 745 cbMsg, sOpcode, abPayload = (None, None, None); 746 while True: 747 # Pending input? 748 if msPendingInputReply is None \ 749 and oStdIn is not None \ 750 and not isinstance(oStdIn, basestring): 751 try: 752 abInput = oStdIn.read(65536); 753 except: 754 reporter.errorXcpt('read standard in'); 755 sFailure = 'exception reading stdin'; 756 rc = None; 757 break; 758 if len(abInput) > 0: 759 oStdIn.uTxsClientCrc32 = zlib.crc32(abInput, oStdIn.uTxsClientCrc32); 760 rc = self.sendMsg('STDIN', (long(oStdIn.uTxsClientCrc32 & 0xffffffff), abInput)); 761 if rc is not True: 762 sFailure = 'sendMsg failure'; 763 break; 764 msPendingInputReply = base.timestampMilli(); 765 continue; 766 767 # Wait for input (500 ms timeout). 768 if cbMsg is None: 769 cbMsg, sOpcode, abPayload = self.recvReply(cMsTimeout=500, fNoDataOk=True); 770 if cbMsg == None: 771 # Check for time out before restarting the loop. 772 # Note! Only doing timeout checking here does mean that 773 # the TXS may prevent us from timing out by 774 # flooding us with data. This is unlikely though. 775 if self.hasTimedOut() \ 776 and ( msPendingInputReply is None \ 777 or base.timestampMilli() - msPendingInputReply > 30000): 778 reporter.maybeErr(self.fErr, 'taskExecEx: timed out'); 779 sFailure = 'timeout'; 780 rc = None; 781 break; 782 # Check that the connection is OK. 783 if not self.oTransport.isConnectionOk(): 784 self.oTransport.disconnect(); 785 sFailure = 'disconnected'; 786 rc = False; 787 break; 788 continue; 789 790 # Handle the response. 791 sOpcode = sOpcode.rstrip(); 792 if sOpcode == 'STDOUT': 793 oOut = oStdOut; 794 elif sOpcode == 'STDERR': 795 oOut = oStdErr; 796 elif sOpcode == 'TESTPIPE': 797 oOut = oTestPipe; 798 else: 799 oOut = None; 800 if oOut is not None: 801 # Output from the process. 802 if len(abPayload) < 4: 803 sFailure = 'malformed output packet (%s, %u bytes)' % (sOpcode, cbMsg); 804 reporter.maybeErr(self.fErr, 'taskExecEx: %s' % (sFailure)); 805 rc = None; 806 break; 807 uStreamCrc32 = getU32(abPayload, 0); 808 oOut.uTxsClientCrc32 = zlib.crc32(abPayload[4:], oOut.uTxsClientCrc32); 809 if uStreamCrc32 != (oOut.uTxsClientCrc32 & 0xffffffff): 810 sFailure = 'crc error - mine=%#x their=%#x (%s, %u bytes)' \ 811 % (oOut.uTxsClientCrc32 & 0xffffffff, uStreamCrc32, sOpcode, cbMsg); 812 reporter.maybeErr(self.fErr, 'taskExecEx: %s' % (sFailure)); 813 rc = None; 814 break; 815 try: 816 oOut.write(abPayload[4:]); 817 except: 818 sFailure = 'exception writing %s' % (sOpcode); 819 reporter.errorXcpt('taskExecEx: %s' % (sFailure)); 820 rc = None; 821 break; 822 elif sOpcode == 'STDINIGN' and msPendingInputReply is not None: 823 # Standard input is ignored. Ignore this condition for now. 824 msPendingInputReply = None; 825 reporter.log('taskExecEx: Standard input is ignored... why?'); 826 del oStdIn.uTxsClientCrc32; 827 oStdIn = '/dev/null'; 828 elif (sOpcode == 'STDINMEM' or sOpcode == 'STDINBAD' or sOpcode == 'STDINCRC')\ 829 and msPendingInputReply is not None: 830 # TXS STDIN error, abort. 831 # TODO: STDINMEM - consider undoing the previous stdin read and try resubmitt it. 832 msPendingInputReply = None; 833 sFailure = 'TXS is out of memory for std input buffering'; 834 reporter.maybeErr(self.fErr, 'taskExecEx: %s' % (sFailure)); 835 rc = None; 836 break; 837 elif sOpcode == 'ACK' and msPendingInputReply is not None: 838 msPendingInputReply = None; 839 elif sOpcode.startswith('PROC '): 840 # Process status message, handle it outside the loop. 841 rc = True; 842 break; 843 else: 844 sFailure = 'Unexpected opcode %s' % (sOpcode); 845 reporter.maybeErr(self.fErr, 'taskExecEx: %s' % (sFailure)); 846 rc = None; 847 break; 848 # Clear the message. 849 cbMsg, sOpcode, abPayload = (None, None, None); 850 851 # If we sent an STDIN packet and didn't get a reply yet, we'll give 852 # TXS some 5 seconds to reply to this. If we don't wait here we'll 853 # get screwed later on if we mix it up with the reply to some other 854 # command. Hackish. 855 if msPendingInputReply is not None: 856 cbMsg2, sOpcode2, abPayload2 = self.oTransport.recvMsg(5000); 857 if cbMsg2 is not None: 858 reporter.log('taskExecEx: Out of order STDIN, got reply: %s, %s, %s [ignored]' 859 % (cbMsg2, sOpcode2, abPayload2)); 860 msPendingInputReply = None; 861 else: 862 reporter.maybeErr(self.fErr, 'taskExecEx: Pending STDIN, no reply after 5 secs!'); 863 self.fScrewedUpMsgState = True; 864 865 # Parse the exit status (True), abort (None) or do nothing (False). 866 if rc is True: 867 if sOpcode == 'PROC OK': 868 rc = True; 869 else: 870 # Do proper parsing some other day if needed: 871 # PROC TOK, PROC TOA, PROC DWN, PROC DOO, 872 # PROC NOK + rc, PROC SIG + sig, PROC ABD, FAILED. 873 rc = False; 874 else: 875 if rc is None: 876 # Abort it. 877 reporter.log('taskExecEx: sending ABORT...'); 878 rc = self.sendMsg('ABORT'); 879 while rc is True: 880 cbMsg, sOpcode, abPayload = self.oTransport.recvMsg(30000); 881 if cbMsg is None: 882 reporter.maybeErr(self.fErr, 'taskExecEx: Pending ABORT, no reply after 30 secs!') 883 self.fScrewedUpMsgState = True; 884 break; 885 if sOpcode.startswith('PROC '): 886 reporter.log('taskExecEx: ABORT reply: %s, %s, %s [ignored]' % (cbMsg, sOpcode, abPayload)); 887 break; 888 reporter.log('taskExecEx: ABORT in process, ignoring reply: %s, %s, %s' % (cbMsg, sOpcode, abPayload)); 889 # Check that the connection is OK before looping. 890 if not self.oTransport.isConnectionOk(): 891 self.oTransport.disconnect(); 892 break; 893 894 # Fake response with the reason why we quit. 895 if sFailure is not None: 896 self.t3oReply = (0, 'EXECFAIL', sFailure); 897 rc = None; 898 else: 899 rc = None; 900 901 # Cleanup. 902 for o in (oStdIn, oStdOut, oStdErr, oTestPipe): 903 if o is not None and not isinstance(o, basestring): 904 del o.uTxsClientCrc32; # pylint: disable=E1103 905 reporter.log('taskExecEx: returns %s' % (rc)); 725 def taskGadgetDestroy(self, iGadgetId): 726 """Destroys the given gadget handle on UTS""" 727 fRc = self.senfMsg("GDGTDTOR", (iGadgetId, )); 728 if fRc is True: 729 fRc = self.recvAckLogged("GDGTDTOR"); 906 730 return rc; 907 731 908 # 909 # Admin tasks 910 # 911 912 def hlpRebootShutdownWaitForAck(self, sCmd): 913 """Wait for reboot/shutodwn ACK.""" 914 rc = self.recvAckLogged(sCmd); 915 if rc is True: 916 # poll a little while for server to disconnect. 917 uMsStart = base.timestampMilli(); 918 while self.oTransport.isConnectionOk() \ 919 and base.timestampMilli() - uMsStart >= 5000: 920 if self.oTransport.isRecvPending(min(500, self.getMsLeft())): 921 break; 922 self.oTransport.disconnect(); 732 def taskGadgetConnect(self, iGadgetId): 733 """Connects the given gadget handle on UTS""" 734 fRc = self.senfMsg("GDGTCNCT", (iGadgetId, )); 735 if fRc is True: 736 fRc = self.recvAckLogged("GDGTCNCT"); 923 737 return rc; 924 738 925 def taskReboot(self): 926 rc = self.sendMsg('REBOOT'); 927 if rc is True: 928 rc = self.hlpRebootShutdownWaitForAck('REBOOT'); 739 def taskGadgetDisconnect(self, iGadgetId): 740 """Disconnects the given gadget handle from UTS""" 741 fRc = self.senfMsg("GDGTDCNT", (iGadgetId, )); 742 if fRc is True: 743 fRc = self.recvAckLogged("GDGTDCNT"); 929 744 return rc; 930 931 def taskShutdown(self):932 rc = self.sendMsg('SHUTDOWN');933 if rc is True:934 rc = self.hlpRebootShutdownWaitForAck('SHUTDOWN');935 return rc;936 937 #938 # CD/DVD control tasks.939 #940 941 ## TODO942 943 #944 # File system tasks945 #946 947 def taskMkDir(self, sRemoteDir, fMode):948 rc = self.sendMsg('MKDIR', (fMode, sRemoteDir));949 if rc is True:950 rc = self.recvAckLogged('MKDIR');951 return rc;952 953 def taskMkDirPath(self, sRemoteDir, fMode):954 rc = self.sendMsg('MKDRPATH', (fMode, sRemoteDir));955 if rc is True:956 rc = self.recvAckLogged('MKDRPATH');957 return rc;958 959 def taskMkSymlink(self, sLinkTarget, sLink):960 rc = self.sendMsg('MKSYMLNK', (sLinkTarget, sLink));961 if rc is True:962 rc = self.recvAckLogged('MKSYMLNK');963 return rc;964 965 def taskRmDir(self, sRemoteDir):966 rc = self.sendMsg('RMDIR', (sRemoteDir,));967 if rc is True:968 rc = self.recvAckLogged('RMDIR');969 return rc;970 971 def taskRmFile(self, sRemoteFile):972 rc = self.sendMsg('RMFILE', (sRemoteFile,));973 if rc is True:974 rc = self.recvAckLogged('RMFILE');975 return rc;976 977 def taskRmSymlink(self, sRemoteSymlink):978 rc = self.sendMsg('RMSYMLNK', (sRemoteSymlink,));979 if rc is True:980 rc = self.recvAckLogged('RMSYMLNK');981 return rc;982 983 def taskRmTree(self, sRemoteTree):984 rc = self.sendMsg('RMTREE', (sRemoteTree,));985 if rc is True:986 rc = self.recvAckLogged('RMTREE');987 return rc;988 989 #def "CHMOD "990 #def "CHOWN "991 #def "CHGRP "992 993 def taskIsDir(self, sRemoteDir):994 rc = self.sendMsg('ISDIR', (sRemoteDir,));995 if rc is True:996 rc = self.recvTrueFalse('ISDIR');997 return rc;998 999 def taskIsFile(self, sRemoteFile):1000 rc = self.sendMsg('ISFILE', (sRemoteFile,));1001 if rc is True:1002 rc = self.recvTrueFalse('ISFILE');1003 return rc;1004 1005 def taskIsSymlink(self, sRemoteSymlink):1006 rc = self.sendMsg('ISSYMLNK', (sRemoteSymlink,));1007 if rc is True:1008 rc = self.recvTrueFalse('ISSYMLNK');1009 return rc;1010 1011 #def "STAT "1012 #def "LSTAT "1013 #def "LIST "1014 1015 def taskUploadFile(self, sLocalFile, sRemoteFile):1016 #1017 # Open the local file (make sure it exist before bothering TXS) and1018 # tell TXS that we want to upload a file.1019 #1020 try:1021 oLocalFile = utils.openNoInherit(sLocalFile, 'rb');1022 except:1023 reporter.errorXcpt('taskUpload: failed to open "%s"' % (sLocalFile));1024 return False;1025 1026 # Common cause with taskUploadStr1027 rc = self.taskUploadCommon(oLocalFile, sRemoteFile);1028 1029 # Cleanup.1030 oLocalFile.close();1031 return rc;1032 1033 def taskUploadString(self, sContent, sRemoteFile):1034 # Wrap sContent in a file like class.1035 class InStringFile(object): # pylint: disable=R09031036 def __init__(self, sContent):1037 self.sContent = sContent;1038 self.off = 0;1039 1040 def read(self, cbMax):1041 cbLeft = len(self.sContent) - self.off;1042 if cbLeft == 0:1043 return "";1044 if cbLeft <= cbMax:1045 sRet = self.sContent[self.off:(self.off + cbLeft)];1046 else:1047 sRet = self.sContent[self.off:(self.off + cbMax)];1048 self.off = self.off + len(sRet);1049 return sRet;1050 1051 oLocalString = InStringFile(sContent);1052 return self.taskUploadCommon(oLocalString, sRemoteFile);1053 1054 def taskUploadCommon(self, oLocalFile, sRemoteFile):1055 """Common worker used by taskUploadFile and taskUploadString."""1056 # Command + ACK.1057 rc = self.sendMsg('PUT FILE', (sRemoteFile,));1058 if rc is True:1059 rc = self.recvAckLogged('PUT FILE');1060 if rc is True:1061 #1062 # Push data packets until eof.1063 #1064 uMyCrc32 = zlib.crc32("");1065 while True:1066 # Read up to 64 KB of data.1067 try:1068 sRaw = oLocalFile.read(65536);1069 except:1070 rc = None;1071 break;1072 1073 # Convert to array - this is silly!1074 abBuf = array.array('B');1075 for i in range(len(sRaw)):1076 abBuf.append(ord(sRaw[i]));1077 sRaw = None;1078 1079 # Update the file stream CRC and send it off.1080 uMyCrc32 = zlib.crc32(abBuf, uMyCrc32);1081 if len(abBuf) == 0:1082 rc = self.sendMsg('DATA EOF', (long(uMyCrc32 & 0xffffffff), ));1083 else:1084 rc = self.sendMsg('DATA ', (long(uMyCrc32 & 0xffffffff), abBuf));1085 if rc is False:1086 break;1087 1088 # Wait for the reply.1089 rc = self.recvAck();1090 if rc is not True:1091 if rc is False:1092 reporter.maybeErr(self.fErr, 'taskUpload: transport error waiting for ACK');1093 else:1094 reporter.maybeErr(self.fErr, 'taskUpload: DATA response was %s: %s' % (rc[0], rc[1]));1095 rc = False;1096 break;1097 1098 # EOF?1099 if len(abBuf) == 0:1100 break;1101 1102 # Send ABORT on ACK and I/O errors.1103 if rc is None:1104 rc = self.sendMsg('ABORT');1105 if rc is True:1106 self.recvAckLogged('ABORT');1107 rc = False;1108 return rc;1109 1110 def taskDownloadFile(self, sRemoteFile, sLocalFile):1111 try:1112 oLocalFile = utils.openNoInherit(sLocalFile, 'wb');1113 except:1114 reporter.errorXcpt('taskDownload: failed to open "%s"' % (sLocalFile));1115 return False;1116 1117 rc = self.taskDownloadCommon(sRemoteFile, oLocalFile);1118 1119 oLocalFile.close();1120 if rc is False:1121 try:1122 os.remove(sLocalFile);1123 except:1124 reporter.errorXcpt();1125 return rc;1126 1127 def taskDownloadString(self, sRemoteFile):1128 # Wrap sContent in a file like class.1129 class OutStringFile(object): # pylint: disable=R09031130 def __init__(self):1131 self.asContent = [];1132 1133 def write(self, sBuf):1134 self.asContent.append(sBuf);1135 return None;1136 1137 oLocalString = OutStringFile();1138 rc = self.taskDownloadCommon(sRemoteFile, oLocalString);1139 if rc is True:1140 if len(oLocalString.asContent) == 0:1141 rc = '';1142 else:1143 rc = ''.join(oLocalString.asContent);1144 return rc;1145 1146 def taskDownloadCommon(self, sRemoteFile, oLocalFile):1147 """Common worker for taskDownloadFile and taskDownloadString."""1148 rc = self.sendMsg('GET FILE', (sRemoteFile,))1149 if rc is True:1150 #1151 # Process data packets until eof.1152 #1153 uMyCrc32 = zlib.crc32("");1154 while rc is True:1155 cbMsg, sOpcode, abPayload = self.recvReply();1156 if cbMsg is None:1157 reporter.maybeErr(self.fErr, 'taskDownload got 3xNone from recvReply.');1158 rc = None;1159 break;1160 1161 # Validate.1162 sOpcode = sOpcode.rstrip();1163 if sOpcode != 'DATA' and sOpcode != 'DATA EOF':1164 reporter.maybeErr(self.fErr, 'taskDownload got a error reply: opcode="%s" details="%s"'1165 % (sOpcode, getSZ(abPayload, 0, "None")));1166 rc = False;1167 break;1168 if sOpcode == 'DATA' and len(abPayload) < 4:1169 reporter.maybeErr(self.fErr, 'taskDownload got a bad DATA packet: len=%u' % (len(abPayload)));1170 rc = None;1171 break;1172 if sOpcode == 'DATA EOF' and len(abPayload) != 4:1173 reporter.maybeErr(self.fErr, 'taskDownload got a bad EOF packet: len=%u' % (len(abPayload)));1174 rc = None;1175 break;1176 1177 # Check the CRC (common for both packets).1178 uCrc32 = getU32(abPayload, 0);1179 if sOpcode == 'DATA':1180 uMyCrc32 = zlib.crc32(abPayload[4:], uMyCrc32);1181 if uCrc32 != (uMyCrc32 & 0xffffffff):1182 reporter.maybeErr(self.fErr, 'taskDownload got a bad CRC: mycrc=%s remotecrc=%s'1183 % (hex(uMyCrc32), hex(uCrc32)));1184 rc = None;1185 break;1186 if sOpcode == 'DATA EOF':1187 rc = self.sendMsg('ACK');1188 break;1189 1190 # Finally, push the data to the file.1191 try:1192 oLocalFile.write(abPayload[4:].tostring());1193 except:1194 reporter.errorXcpt('I/O error writing to "%s"' % (sRemoteFile));1195 rc = None;1196 break;1197 rc = self.sendMsg('ACK');1198 1199 # Send NACK on validation and I/O errors.1200 if rc is None:1201 rc = self.sendMsg('NACK');1202 rc = False;1203 return rc;1204 1205 def taskUnpackFile(self, sRemoteFile, sRemoteDir):1206 rc = self.sendMsg('UNPKFILE', (sRemoteFile, sRemoteDir));1207 if rc is True:1208 rc = self.recvAckLogged('UNPKFILE');1209 return rc;1210 1211 # pylint: enable=C01111212 1213 745 1214 746 # … … 1269 801 return self.asyncToSync(self.asyncDisconnect, cMsTimeout, fIgnoreErrors); 1270 802 1271 def asyncUuid(self, cMsTimeout = 30000, fIgnoreErrors = False):1272 """1273 Initiates a task for getting the TXS UUID.1274 1275 Returns True on success, False on failure (logged).1276 1277 The task returns UUID string (in {}) on success and False on failure.1278 """1279 return self.startTask(cMsTimeout, fIgnoreErrors, "bye", self.taskUuid);1280 1281 def syncUuid(self, cMsTimeout = 30000, fIgnoreErrors = False):1282 """Synchronous version."""1283 return self.asyncToSync(self.asyncUuid, cMsTimeout, fIgnoreErrors);1284 1285 803 # 1286 # Public methods - execution.804 # Public methods - gadget API 1287 805 # 1288 806 1289 def asyncExecEx(self, sExecName, asArgs = (), asAddEnv = (), # pylint: disable=R0913 1290 oStdIn = None, oStdOut = None, oStdErr = None, oTestPipe = None, 1291 sAsUser = "", cMsTimeout = 3600000, fIgnoreErrors = False): 1292 """ 1293 Initiates a exec process task. 1294 1295 Returns True on success, False on failure (logged). 1296 1297 The task returns True if the process exited normally with status code 0. 1298 The task returns None if on failure prior to executing the process, and 1299 False if the process exited with a different status or in an abnormal 1300 manner. Both None and False are logged of course and further info can 1301 also be obtained by getLastReply(). 1302 1303 The oStdIn, oStdOut, oStdErr and oTestPipe specifiy how to deal with 1304 these streams. If None, no special action is taken and the output goes 1305 to where ever the TXS sends its output, and ditto for input. 1306 - To send to / read from the bitbucket, pass '/dev/null'. 1307 - To redirect to/from a file, just specify the remote filename. 1308 - To append to a file use '>>' followed by the remote filename. 1309 - To pipe the stream to/from the TXS, specify a file like 1310 object. For StdIn a non-blocking read() method is required. For 1311 the other a write() method is required. Watch out for deadlock 1312 conditions between StdIn and StdOut/StdErr/TestPipe piping. 1313 """ 1314 return self.startTask(cMsTimeout, fIgnoreErrors, "exec", self.taskExecEx, 1315 (sExecName, long(0), asArgs, asAddEnv, oStdIn, 1316 oStdOut, oStdErr, oTestPipe, sAsUser)); 1317 1318 def syncExecEx(self, sExecName, asArgs = (), asAddEnv = (), # pylint: disable=R0913 1319 oStdIn = '/dev/null', oStdOut = '/dev/null', 1320 oStdErr = '/dev/null', oTestPipe = '/dev/null', 1321 sAsUser = '', cMsTimeout = 3600000, fIgnoreErrors = False): 1322 """Synchronous version.""" 1323 return self.asyncToSync(self.asyncExecEx, sExecName, asArgs, asAddEnv, oStdIn, oStdOut, \ 1324 oStdErr, oTestPipe, sAsUser, cMsTimeout, fIgnoreErrors); 1325 1326 def asyncExec(self, sExecName, asArgs = (), asAddEnv = (), sAsUser = "", fWithTestPipe = True, sPrefix = '', \ 1327 cMsTimeout = 3600000, fIgnoreErrors = False): 1328 """ 1329 Initiates a exec process test task. 1330 1331 Returns True on success, False on failure (logged). 1332 1333 The task returns True if the process exited normally with status code 0. 1334 The task returns None if on failure prior to executing the process, and 1335 False if the process exited with a different status or in an abnormal 1336 manner. Both None and False are logged of course and further info can 1337 also be obtained by getLastReply(). 1338 1339 Standard in is taken from /dev/null. While both standard output and 1340 standard error goes directly to reporter.log(). The testpipe is piped 1341 to reporter.xxxx. 1342 """ 1343 1344 sStdIn = '/dev/null'; 1345 oStdOut = reporter.FileWrapper('%sstdout' % sPrefix); 1346 oStdErr = reporter.FileWrapper('%sstderr' % sPrefix); 1347 if fWithTestPipe: oTestPipe = reporter.FileWrapperTestPipe(); 1348 else: oTestPipe = '/dev/null'; 1349 1350 return self.startTask(cMsTimeout, fIgnoreErrors, "exec", self.taskExecEx, 1351 (sExecName, long(0), asArgs, asAddEnv, sStdIn, oStdOut, oStdErr, oTestPipe, sAsUser)); 1352 1353 def syncExec(self, sExecName, asArgs = (), asAddEnv = (), sAsUser = '', fWithTestPipe = True, sPrefix = '', 1354 cMsTimeout = 3600000, fIgnoreErrors = False): 1355 """Synchronous version.""" 1356 return self.asyncToSync(self.asyncExec, sExecName, asArgs, asAddEnv, sAsUser, fWithTestPipe, sPrefix, \ 1357 cMsTimeout, fIgnoreErrors); 1358 1359 # 1360 # Public methods - file system 1361 # 1362 1363 def asyncReboot(self, cMsTimeout = 30000, fIgnoreErrors = False): 1364 """ 1365 Initiates a reboot task. 1366 1367 Returns True on success, False on failure (logged). 1368 1369 The task returns True on success, False on failure (logged). The 1370 session will be disconnected on successful task completion. 1371 """ 1372 return self.startTask(cMsTimeout, fIgnoreErrors, "reboot", self.taskReboot, ()); 1373 1374 def syncReboot(self, cMsTimeout = 30000, fIgnoreErrors = False): 1375 """Synchronous version.""" 1376 return self.asyncToSync(self.asyncReboot, cMsTimeout, fIgnoreErrors); 1377 1378 def asyncShutdown(self, cMsTimeout = 30000, fIgnoreErrors = False): 1379 """ 1380 Initiates a shutdown task. 1381 1382 Returns True on success, False on failure (logged). 1383 1384 The task returns True on success, False on failure (logged). 1385 """ 1386 return self.startTask(cMsTimeout, fIgnoreErrors, "shutdown", self.taskShutdown, ()); 1387 1388 def syncShutdown(self, cMsTimeout = 30000, fIgnoreErrors = False): 1389 """Synchronous version.""" 1390 return self.asyncToSync(self.asyncShutdown, cMsTimeout, fIgnoreErrors); 1391 1392 1393 # 1394 # Public methods - file system 1395 # 1396 1397 def asyncMkDir(self, sRemoteDir, fMode = 0700, cMsTimeout = 30000, fIgnoreErrors = False): 1398 """ 1399 Initiates a mkdir task. 1400 1401 Returns True on success, False on failure (logged). 1402 1403 The task returns True on success, False on failure (logged). 1404 """ 1405 return self.startTask(cMsTimeout, fIgnoreErrors, "mkDir", self.taskMkDir, (sRemoteDir, long(fMode))); 1406 1407 def syncMkDir(self, sRemoteDir, fMode = 0700, cMsTimeout = 30000, fIgnoreErrors = False): 1408 """Synchronous version.""" 1409 return self.asyncToSync(self.asyncMkDir, sRemoteDir, long(fMode), cMsTimeout, fIgnoreErrors); 1410 1411 def asyncMkDirPath(self, sRemoteDir, fMode = 0700, cMsTimeout = 30000, fIgnoreErrors = False): 1412 """ 1413 Initiates a mkdir -p task. 1414 1415 Returns True on success, False on failure (logged). 1416 1417 The task returns True on success, False on failure (logged). 1418 """ 1419 return self.startTask(cMsTimeout, fIgnoreErrors, "mkDirPath", self.taskMkDirPath, (sRemoteDir, long(fMode))); 1420 1421 def syncMkDirPath(self, sRemoteDir, fMode = 0700, cMsTimeout = 30000, fIgnoreErrors = False): 1422 """Synchronous version.""" 1423 return self.asyncToSync(self.asyncMkDirPath, sRemoteDir, long(fMode), cMsTimeout, fIgnoreErrors); 1424 1425 def asyncMkSymlink(self, sLinkTarget, sLink, cMsTimeout = 30000, fIgnoreErrors = False): 1426 """ 1427 Initiates a symlink task. 1428 1429 Returns True on success, False on failure (logged). 1430 1431 The task returns True on success, False on failure (logged). 1432 """ 1433 return self.startTask(cMsTimeout, fIgnoreErrors, "mkSymlink", self.taskMkSymlink, (sLinkTarget, sLink)); 1434 1435 def syncMkSymlink(self, sLinkTarget, sLink, cMsTimeout = 30000, fIgnoreErrors = False): 1436 """Synchronous version.""" 1437 return self.asyncToSync(self.asyncMkSymlink, sLinkTarget, sLink, cMsTimeout, fIgnoreErrors); 1438 1439 def asyncRmDir(self, sRemoteDir, cMsTimeout = 30000, fIgnoreErrors = False): 1440 """ 1441 Initiates a rmdir task. 1442 1443 Returns True on success, False on failure (logged). 1444 1445 The task returns True on success, False on failure (logged). 1446 """ 1447 return self.startTask(cMsTimeout, fIgnoreErrors, "rmDir", self.taskRmDir, (sRemoteDir,)); 1448 1449 def syncRmDir(self, sRemoteDir, cMsTimeout = 30000, fIgnoreErrors = False): 1450 """Synchronous version.""" 1451 return self.asyncToSync(self.asyncRmDir, sRemoteDir, cMsTimeout, fIgnoreErrors); 1452 1453 def asyncRmFile(self, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1454 """ 1455 Initiates a rmfile task. 1456 1457 Returns True on success, False on failure (logged). 1458 1459 The task returns True on success, False on failure (logged). 1460 """ 1461 return self.startTask(cMsTimeout, fIgnoreErrors, "rmFile", self.taskRmFile, (sRemoteFile,)); 1462 1463 def syncRmFile(self, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1464 """Synchronous version.""" 1465 return self.asyncToSync(self.asyncRmFile, sRemoteFile, cMsTimeout, fIgnoreErrors); 1466 1467 def asyncRmSymlink(self, sRemoteSymlink, cMsTimeout = 30000, fIgnoreErrors = False): 1468 """ 1469 Initiates a rmsymlink task. 1470 1471 Returns True on success, False on failure (logged). 1472 1473 The task returns True on success, False on failure (logged). 1474 """ 1475 return self.startTask(cMsTimeout, fIgnoreErrors, "rmSymlink", self.taskRmSymlink, (sRemoteSymlink,)); 1476 1477 def syncRmSymlink(self, sRemoteSymlink, cMsTimeout = 30000, fIgnoreErrors = False): 1478 """Synchronous version.""" 1479 return self.asyncToSync(self.asyncRmSymlink, sRemoteSymlink, cMsTimeout, fIgnoreErrors); 1480 1481 def asyncRmTree(self, sRemoteTree, cMsTimeout = 30000, fIgnoreErrors = False): 1482 """ 1483 Initiates a rmtree task. 1484 1485 Returns True on success, False on failure (logged). 1486 1487 The task returns True on success, False on failure (logged). 1488 """ 1489 return self.startTask(cMsTimeout, fIgnoreErrors, "rmTree", self.taskRmTree, (sRemoteTree,)); 1490 1491 def syncRmTree(self, sRemoteTree, cMsTimeout = 30000, fIgnoreErrors = False): 1492 """Synchronous version.""" 1493 return self.asyncToSync(self.asyncRmTree, sRemoteTree, cMsTimeout, fIgnoreErrors); 1494 1495 #def "CHMOD " 1496 #def "CHOWN " 1497 #def "CHGRP " 1498 1499 def asyncIsDir(self, sRemoteDir, cMsTimeout = 30000, fIgnoreErrors = False): 1500 """ 1501 Initiates a is-dir query task. 1502 1503 Returns True on success, False on failure (logged). 1504 1505 The task returns True if it's a directory, False if it isn't, and 1506 None on error (logged). 1507 """ 1508 return self.startTask(cMsTimeout, fIgnoreErrors, "isDir", self.taskIsDir, (sRemoteDir,)); 1509 1510 def syncIsDir(self, sRemoteDir, cMsTimeout = 30000, fIgnoreErrors = False): 1511 """Synchronous version.""" 1512 return self.asyncToSync(self.asyncIsDir, sRemoteDir, cMsTimeout, fIgnoreErrors); 1513 1514 def asyncIsFile(self, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1515 """ 1516 Initiates a is-file query task. 1517 1518 Returns True on success, False on failure (logged). 1519 1520 The task returns True if it's a file, False if it isn't, and None on 1521 error (logged). 1522 """ 1523 return self.startTask(cMsTimeout, fIgnoreErrors, "isFile", self.taskIsFile, (sRemoteFile,)); 1524 1525 def syncIsFile(self, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1526 """Synchronous version.""" 1527 return self.asyncToSync(self.asyncIsFile, sRemoteFile, cMsTimeout, fIgnoreErrors); 1528 1529 def asyncIsSymlink(self, sRemoteSymlink, cMsTimeout = 30000, fIgnoreErrors = False): 1530 """ 1531 Initiates a is-symbolic-link query task. 1532 1533 Returns True on success, False on failure (logged). 1534 1535 The task returns True if it's a symbolic linke, False if it isn't, and 1536 None on error (logged). 1537 """ 1538 return self.startTask(cMsTimeout, fIgnoreErrors, "isSymlink", self.taskIsSymlink, (sRemoteSymlink,)); 1539 1540 def syncIsSymlink(self, sRemoteSymlink, cMsTimeout = 30000, fIgnoreErrors = False): 1541 """Synchronous version.""" 1542 return self.asyncToSync(self.asyncIsSymlink, sRemoteSymlink, cMsTimeout, fIgnoreErrors); 1543 1544 #def "STAT " 1545 #def "LSTAT " 1546 #def "LIST " 1547 1548 def asyncUploadFile(self, sLocalFile, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1549 """ 1550 Initiates a download query task. 1551 1552 Returns True on success, False on failure (logged). 1553 1554 The task returns True on success, False on failure (logged). 1555 """ 1556 return self.startTask(cMsTimeout, fIgnoreErrors, "upload", self.taskUploadFile, (sLocalFile, sRemoteFile)); 1557 1558 def syncUploadFile(self, sLocalFile, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1559 """Synchronous version.""" 1560 return self.asyncToSync(self.asyncUploadFile, sLocalFile, sRemoteFile, cMsTimeout, fIgnoreErrors); 1561 1562 def asyncUploadString(self, sContent, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1563 """ 1564 Initiates a upload string task. 1565 1566 Returns True on success, False on failure (logged). 1567 1568 The task returns True on success, False on failure (logged). 1569 """ 1570 return self.startTask(cMsTimeout, fIgnoreErrors, "uploadString", self.taskUploadString, (sContent, sRemoteFile)); 1571 1572 def syncUploadString(self, sContent, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1573 """Synchronous version.""" 1574 return self.asyncToSync(self.asyncUploadString, sContent, sRemoteFile, cMsTimeout, fIgnoreErrors); 1575 1576 def asyncDownloadFile(self, sRemoteFile, sLocalFile, cMsTimeout = 30000, fIgnoreErrors = False): 1577 """ 1578 Initiates a download file task. 1579 1580 Returns True on success, False on failure (logged). 1581 1582 The task returns True on success, False on failure (logged). 1583 """ 1584 return self.startTask(cMsTimeout, fIgnoreErrors, "downloadFile", self.taskDownloadFile, (sRemoteFile, sLocalFile)); 1585 1586 def syncDownloadFile(self, sRemoteFile, sLocalFile, cMsTimeout = 30000, fIgnoreErrors = False): 1587 """Synchronous version.""" 1588 return self.asyncToSync(self.asyncDownloadFile, sRemoteFile, sLocalFile, cMsTimeout, fIgnoreErrors); 1589 1590 def asyncDownloadString(self, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1591 """ 1592 Initiates a download string task. 1593 1594 Returns True on success, False on failure (logged). 1595 1596 The task returns a byte string on success, False on failure (logged). 1597 """ 1598 return self.startTask(cMsTimeout, fIgnoreErrors, "downloadString", self.taskDownloadString, (sRemoteFile,)); 1599 1600 def syncDownloadString(self, sRemoteFile, cMsTimeout = 30000, fIgnoreErrors = False): 1601 """Synchronous version.""" 1602 return self.asyncToSync(self.asyncDownloadString, sRemoteFile, cMsTimeout, fIgnoreErrors); 1603 1604 def asyncUnpackFile(self, sRemoteFile, sRemoteDir, cMsTimeout = 30000, fIgnoreErrors = False): 1605 """ 1606 Initiates a unpack file task. 1607 1608 Returns True on success, False on failure (logged). 1609 1610 The task returns True on success, False on failure (logged). 1611 """ 1612 return self.startTask(cMsTimeout, fIgnoreErrors, "unpackFile", self.taskUnpackFile, \ 1613 (sRemoteFile, sRemoteDir)); 1614 1615 def syncUnpackFile(self, sRemoteFile, sRemoteDir, cMsTimeout = 30000, fIgnoreErrors = False): 1616 """Synchronous version.""" 1617 return self.asyncToSync(self.asyncUnpackFile, sRemoteFile, sRemoteDir, cMsTimeout, fIgnoreErrors); 807 def 1618 808 1619 809 1620 810 class TransportTcp(TransportBase): 1621 811 """ 1622 TCP transport layer for the TXS client session class.1623 """ 1624 1625 def __init__(self, sHostname, uPort , fReversedSetup):812 TCP transport layer for the UTS client session class. 813 """ 814 815 def __init__(self, sHostname, uPort): 1626 816 """ 1627 817 Save the parameters. The session will call us back to make the … … 1630 820 TransportBase.__init__(self, utils.getCallerName()); 1631 821 self.sHostname = sHostname; 1632 self.fReversedSetup = fReversedSetup; 1633 self.uPort = uPort if uPort is not None else 5042 if fReversedSetup is False else 5048; 822 self.uPort = uPort if uPort is not None else 6042; 1634 823 self.oSocket = None; 1635 824 self.oWakeupW = None; … … 1641 830 1642 831 def toString(self): 1643 return '<%s sHostname=%s, fReversedSetup=%s,uPort=%s, oSocket=%s,'\832 return '<%s sHostname=%s, uPort=%s, oSocket=%s,'\ 1644 833 ' fConnectCanceled=%s, fIsConnecting=%s, oCv=%s, abReadAhead=%s>' \ 1645 % (TransportBase.toString(self), self.sHostname, self. fReversedSetup, self.uPort, self.oSocket,834 % (TransportBase.toString(self), self.sHostname, self.uPort, self.oSocket, 1646 835 self.fConnectCanceled, self.fIsConnecting, self.oCv, self.abReadAhead); 1647 836 … … 1732 921 self.oCv.release(); 1733 922 1734 def _connectAsServer(self, oSocket, oWakeupR, cMsTimeout):1735 """ Connects to the TXS server as server, i.e. the reversed setup. """1736 assert(self.fReversedSetup);1737 1738 reporter.log2('TransportTcp::_connectAsServer: oSocket=%s, cMsTimeout=%u' % (oSocket, cMsTimeout));1739 1740 # Workaround for bind() failure...1741 try:1742 oSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);1743 except:1744 reporter.errorXcpt('socket.listen(1) failed');1745 return None;1746 1747 # Bind the socket and make it listen.1748 try:1749 oSocket.bind((self.sHostname, self.uPort));1750 except:1751 reporter.errorXcpt('socket.bind((%s,%s)) failed' % (self.sHostname, self.uPort));1752 return None;1753 try:1754 oSocket.listen(1);1755 except:1756 reporter.errorXcpt('socket.listen(1) failed');1757 return None;1758 1759 # Accept connections.1760 oClientSocket = None;1761 tClientAddr = None;1762 try:1763 (oClientSocket, tClientAddr) = oSocket.accept();1764 except socket.error, e:1765 if not self.__isInProgressXcpt(e):1766 raise;1767 1768 # Do the actual waiting.1769 reporter.log2('TransportTcp::accept: operation in progress (%s)...' % (e,));1770 try:1771 select.select([oSocket, oWakeupR], [], [oSocket, oWakeupR], cMsTimeout / 1000.0);1772 except socket.error, e:1773 if e[0] != errno.EBADF or not self.fConnectCanceled:1774 raise;1775 reporter.log('socket.select() on accept was canceled');1776 return None;1777 except:1778 reporter.logXcpt('socket.select() on accept');1779 1780 # Try accept again.1781 try:1782 (oClientSocket, tClientAddr) = oSocket.accept();1783 except socket.error, e:1784 if not self.__isInProgressXcpt(e):1785 if e[0] != errno.EBADF or not self.fConnectCanceled:1786 raise;1787 reporter.log('socket.accept() was canceled');1788 return None;1789 reporter.log('socket.accept() timed out');1790 return False;1791 except:1792 reporter.errorXcpt('socket.accept() failed');1793 return None;1794 except:1795 reporter.errorXcpt('socket.accept() failed');1796 return None;1797 1798 # Store the connected socket and throw away the server socket.1799 self.oCv.acquire();1800 if not self.fConnectCanceled:1801 self.oSocket.close();1802 self.oSocket = oClientSocket;1803 self.sHostname = "%s:%s" % (tClientAddr[0], tClientAddr[1]);1804 self.oCv.release();1805 return True;1806 1807 923 def _connectAsClient(self, oSocket, oWakeupR, cMsTimeout): 1808 """ Connects to the TXS server as client. """ 1809 assert(not self.fReversedSetup); 924 """ Connects to the UTS server as client. """ 1810 925 1811 926 # Connect w/ timeouts. … … 1884 999 if oWakeupR is None: 1885 1000 oWakeupR = oSocket; # Avoid select failure. 1886 if self.fReversedSetup: 1887 rc = self._connectAsServer(oSocket, oWakeupR, cMsTimeout); 1888 else: 1889 rc = self._connectAsClient(oSocket, oWakeupR, cMsTimeout); 1001 rc = self._connectAsClient(oSocket, oWakeupR, cMsTimeout); 1890 1002 oSocket = None; 1891 1003 … … 2082 1194 2083 1195 2084 def openTcpSession(cMsTimeout, sHostname, uPort = None, fReversedSetup = False, cMsIdleFudge = 0): 2085 """ 2086 Opens a connection to a Test Execution Service via TCP, given its name. 2087 """ 2088 reporter.log2('openTcpSession(%s, %s, %s, %s, %s)' % \ 2089 (cMsTimeout, sHostname, uPort, fReversedSetup, cMsIdleFudge)); 2090 try: 2091 oTransport = TransportTcp(sHostname, uPort, fReversedSetup); 2092 oSession = Session(oTransport, cMsTimeout, cMsIdleFudge); 2093 except: 2094 reporter.errorXcpt(None, 15); 2095 return None; 2096 return oSession; 2097 2098 2099 def tryOpenTcpSession(cMsTimeout, sHostname, uPort = None, fReversedSetup = False, cMsIdleFudge = 0): 2100 """ 2101 Tries to open a connection to a Test Execution Service via TCP, given its name. 2102 2103 This differs from openTcpSession in that it won't log a connection failure 2104 as an error. 2105 """ 2106 try: 2107 oTransport = TransportTcp(sHostname, uPort, fReversedSetup); 2108 oSession = Session(oTransport, cMsTimeout, cMsIdleFudge, fTryConnect = True); 2109 except: 2110 reporter.errorXcpt(None, 15); 2111 return None; 2112 return oSession; 2113 1196 class UsbGadget(object): 1197 """ 1198 USB Gadget control class using the USBT Test Service to talk to the external 1199 board behaving like a USB device. 1200 """ 1201 1202 def __init__(self): 1203 self.oUtsSession = None; 1204 self.sImpersonation = g_ksGadgetImpersonationInvalid; 1205 self.sGadgetType = g_ksGadgetTypeInvalid; 1206 self.idGadget = None; 1207 1208 def _clearImpersonation(self): 1209 """ 1210 Removes the current impersonation of the gadget. 1211 """ 1212 fRc = True; 1213 1214 if self.idGadget is not None: 1215 fRc = self.oUtsSession.syncGadgetDestroy(self.idGadget); 1216 1217 return fRc; 1218 1219 def disconnectUsb(self): 1220 """ 1221 Disconnects the USB gadget from the host. (USB connection not network 1222 connection used for control) 1223 """ 1224 return self.oUtsSession.syncGadgetDisconnect(self.idGadget); 1225 1226 def connectUsb(self): 1227 """ 1228 Connect the USB gadget to the host. 1229 """ 1230 return self.oUtsSession.syncGadgetConnect(self.idGadget); 1231 1232 def impersonate(self, sImpersonation): 1233 """ 1234 Impersonate a given device. 1235 """ 1236 1237 # Clear any previous impersonation 1238 self._clearImpersonation(); 1239 self.sImpersonation = sImpersonation; 1240 1241 fRc = False; 1242 if sImpersonation == g_ksGadgetImpersonationTest: 1243 fRc = self.oUtsSession.syncGadgetCreate(g_kiGadgetTypeTest); 1244 else: 1245 reporter.log('Invalid or unsupported impersonation'); 1246 1247 return fRc; 1248 1249 def connectTo(self, cMsTimeout, sHostname, uPort = None): 1250 """ 1251 Connects to the specified target device. 1252 Returns True on Success. 1253 Returns False otherwise. 1254 """ 1255 fRc = True; 1256 1257 reporter.log2('openTcpSession(%s, %s, %s, %s)' % \ 1258 (cMsTimeout, sHostname, uPort, cMsIdleFudge)); 1259 try: 1260 oTransport = TransportTcp(sHostname, uPort); 1261 self.oUtsSession = Session(oTransport, cMsTimeout, cMsIdleFudge); 1262 1263 if self.oUtsSession is not None: 1264 fDone = self.oUtsSession.waitForTask(30*1000); 1265 print 'connect: waitForTask -> %s, result %s' % (fDone, self.oUtsSession.getResult()); 1266 if fDone is True and self.oUtsSession.isSuccess(): 1267 fRc = True; 1268 else: 1269 fRc = False; 1270 else: 1271 fRc = False; 1272 1273 if fRc: 1274 fRc = self._prepareGadget(); 1275 except: 1276 reporter.errorXcpt(None, 15); 1277 return False; 1278 1279 return fRc; 1280 1281 def disconnectFrom(self): 1282 """ 1283 Disconnects from the target device. 1284 """ 1285 fRc = True; 1286 1287 self._clearImpersonation(); 1288 self._cleanupGadget(); 1289 if self.oUtsSession is not None: 1290 fRc = self.oUtsSession.syncDisconnect(); 1291 1292 return fRc; 1293
Note:
See TracChangeset
for help on using the changeset viewer.

