Coverage Report - org.jscsi.target.connection.stage.fullfeature.TextNegotiationStage
 
Classes in this File Line Coverage Branch Coverage Complexity
TextNegotiationStage
0%
0/28
0%
0/28
7
 
 1  
 package org.jscsi.target.connection.stage.fullfeature;
 2  
 
 3  
 
 4  
 import java.io.IOException;
 5  
 import java.nio.ByteBuffer;
 6  
 import java.security.DigestException;
 7  
 import java.util.List;
 8  
 import java.util.Vector;
 9  
 
 10  
 import org.jscsi.exception.InternetSCSIException;
 11  
 import org.jscsi.parser.BasicHeaderSegment;
 12  
 import org.jscsi.parser.ProtocolDataUnit;
 13  
 import org.jscsi.target.connection.TargetPduFactory;
 14  
 import org.jscsi.target.connection.phase.TargetFullFeaturePhase;
 15  
 import org.jscsi.target.settings.SettingsException;
 16  
 import org.jscsi.target.settings.TextKeyword;
 17  
 import org.jscsi.target.settings.TextParameter;
 18  
 import org.jscsi.target.util.ReadWrite;
 19  
 import org.slf4j.Logger;
 20  
 import org.slf4j.LoggerFactory;
 21  
 
 22  
 
 23  
 /**
 24  
  * A stage for processing requests by the initiator for a list of all targets available through the iSCSI portal and for
 25  
  * negotiating connection parameters in the full feature phase.
 26  
  * <p>
 27  
  * That latter functionality is currently not implemented.
 28  
  * 
 29  
  * @author Andreas Ergenzinger
 30  
  */
 31  
 public final class TextNegotiationStage extends TargetFullFeatureStage {
 32  
 
 33  0
     private static final Logger LOGGER = LoggerFactory.getLogger(TextNegotiationStage.class);
 34  
 
 35  
     public TextNegotiationStage (TargetFullFeaturePhase targetFullFeaturePhase) {
 36  0
         super(targetFullFeaturePhase);
 37  0
     }
 38  
 
 39  
     @Override
 40  
     public void execute (ProtocolDataUnit pdu) throws IOException , InterruptedException , InternetSCSIException , DigestException , SettingsException {
 41  
 
 42  0
         final BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
 43  
 
 44  0
         final int initiatorTaskTag = bhs.getInitiatorTaskTag();
 45  
 
 46  0
         final String textRequest = new String(pdu.getDataSegment().array());
 47  
 
 48  0
         LOGGER.debug("text request: " + textRequest);
 49  
 
 50  0
         ByteBuffer replyDataSegment = null;// for later
 51  
 
 52  
         // tokenize key-value pairs
 53  0
         final List<String> requestKeyValuePairs = TextParameter.tokenizeKeyValuePairs(textRequest);
 54  
 
 55  0
         final List<String> responseKeyValuePairs = new Vector<String>();
 56  
 
 57  
         // process SendTargets command
 58  0
         if (requestKeyValuePairs != null) {
 59  
             // A SendTargets command consists of a single Text request PDU. This
 60  
             // PDU contains exactly one text key and value.
 61  0
             String sendTargetsValue = null;
 62  
 
 63  0
             if (requestKeyValuePairs.size() == 1) sendTargetsValue = TextParameter.getSuffix(requestKeyValuePairs.get(0),// string
 64  
                     TextKeyword.SEND_TARGETS + TextKeyword.EQUALS);// prefix
 65  
 
 66  0
             if (sendTargetsValue != null) {
 67  
                 // initiator wants target information
 68  
                 /*
 69  
                  * ALL must be supported in discovery session and must not be supported in operational session.
 70  
                  * <name-of-this-target> must be supported in discovery session (and it does no harm to support it in
 71  
                  * the operational session). <nothing> must be supported in the operational session and will only return
 72  
                  * info on the target the initiator is connected to, this means no info is returned in discovery
 73  
                  * session. outcome table | discovery |operational| ---------------+-----------+-----------| ALL | TN +
 74  
                  * TA | fail | ---------------+-----------+-----------| <this target> | TA | TA |
 75  
                  * ---------------+-----------+-----------| <other target> | fail | fail |
 76  
                  * ---------------+-----------+-----------| <nothing> | fail | TA | TN stands for TargetName, TA for
 77  
                  * TargetAddress "fail" means no text response.
 78  
                  */
 79  0
                 final boolean normal = session.isNormalSession();
 80  0
                 final boolean sendTargetName = // see upper table
 81  
                 !normal && sendTargetsValue.equals(TextKeyword.ALL);
 82  0
                 final boolean sendTargetAddress = // see upper table
 83  
                 (!normal && sendTargetsValue.equals(TextKeyword.ALL)) || (session.getTargetServer().isValidTargetName(sendTargetsValue)) || (normal && sendTargetsValue.length() == 0);
 84  
 
 85  
                 /*
 86  
                  * A target record consists of a TargetName key-value pair followed by one or more TargetAddress
 87  
                  * key-value pairs for that TargetName. (table above takes precedence to these definitions)
 88  
                  */
 89  
 
 90  
                 // add TargetName
 91  0
                 if (sendTargetName) {
 92  0
                     for (String curTargetName : session.getTargetServer().getTargetNames()) {
 93  0
                         responseKeyValuePairs.add(TextParameter.toKeyValuePair(TextKeyword.TARGET_NAME, curTargetName));
 94  
                         // add TargetAddress
 95  0
                         if (sendTargetAddress) responseKeyValuePairs.add(TextParameter.toKeyValuePair(TextKeyword.TARGET_ADDRESS, session.getTargetServer().getConfig().getTargetAddress() + // domain
 96  
                         TextKeyword.COLON + // :
 97  
                         session.getTargetServer().getConfig().getPort() + // port
 98  
                         TextKeyword.COMMA + // ,
 99  
                         session.getTargetServer().getConfig().getTargetPortalGroupTag())); // groupTag)
 100  
                     }
 101  
                 } else {
 102  
                     // We're here if they sent us a target name and are asking for the address (I think)
 103  0
                     if (sendTargetAddress) responseKeyValuePairs.add(TextParameter.toKeyValuePair(TextKeyword.TARGET_ADDRESS, session.getTargetServer().getConfig().getTargetAddress() + // domain
 104  
                     TextKeyword.COLON + // :
 105  
                     session.getTargetServer().getConfig().getPort() + // port
 106  
                     TextKeyword.COMMA + // ,
 107  
                     session.getTargetServer().getConfig().getTargetPortalGroupTag())); // groupTag)
 108  
                 }
 109  
 
 110  
             } else {
 111  
                 // initiator wants to negotiate or declare parameters
 112  
                 // TODO
 113  
             }
 114  
 
 115  
             // concatenate and serialize reply
 116  0
             final String replyString = TextParameter.concatenateKeyValuePairs(responseKeyValuePairs);
 117  
 
 118  0
             LOGGER.debug("text negotiation stage reply: " + replyString);
 119  
 
 120  0
             replyDataSegment = ReadWrite.stringToTextDataSegments(replyString, settings.getMaxRecvDataSegmentLength())[0];// definitely
 121  
                                                                                                                           // fits
 122  
                                                                                                                           // into
 123  
                                                                                                                           // one
 124  
                                                                                                                           // data
 125  
                                                                                                                           // segment
 126  
         }
 127  
 
 128  
         // send reply
 129  0
         final ProtocolDataUnit responsePdu = TargetPduFactory.createTextResponsePdu(true,// finalFlag
 130  
                 false,// continueFlag
 131  
                 0,// logicalUnitNumber
 132  
                 initiatorTaskTag, 0xffffffff,// targetTransferTag
 133  
                 replyDataSegment);// dataSegment
 134  
 
 135  0
         connection.sendPdu(responsePdu);
 136  0
     }
 137  
 
 138  
 }