View Javadoc

1   /**
2    * Copyright (c) 2012, University of Konstanz, Distributed Systems Group All rights reserved.
3    * 
4    * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
5    * following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of
6    * conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice,
7    * this list of conditions and the following disclaimer in the documentation and/or other materials provided with the
8    * distribution. * Neither the name of the University of Konstanz nor the names of its contributors may be used to
9    * endorse or promote products derived from this software without specific prior written permission.
10   * 
11   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
12   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13   * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
14   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
17   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18   */
19  package org.jscsi.initiator.connection.state;
20  
21  
22  import org.jscsi.exception.InternetSCSIException;
23  import org.jscsi.initiator.connection.Connection;
24  import org.jscsi.initiator.connection.phase.FullFeaturePhase;
25  import org.jscsi.initiator.connection.phase.LoginOperationalNegotiationPhase;
26  import org.jscsi.parser.ProtocolDataUnit;
27  import org.jscsi.parser.datasegment.DataSegmentFactory;
28  import org.jscsi.parser.datasegment.DataSegmentFactory.DataSegmentFormat;
29  import org.jscsi.parser.datasegment.IDataSegment;
30  import org.jscsi.parser.datasegment.OperationalTextKey;
31  import org.jscsi.parser.login.LoginResponseParser;
32  import org.jscsi.parser.login.LoginStage;
33  
34  
35  /**
36   * <h1>LoginResponseState</h1>
37   * <p/>
38   * This state handles a Login Response.
39   * 
40   * @author Volker Wildi
41   */
42  public final class LoginResponseState extends AbstractState {
43  
44      // --------------------------------------------------------------------------
45      // --------------------------------------------------------------------------
46  
47      /**
48       * The Next Stage of the login process, that the iSCSI Target wants to transit to.
49       */
50      private final LoginStage nextStage;
51  
52      // --------------------------------------------------------------------------
53      // --------------------------------------------------------------------------
54  
55      /**
56       * Constructor to create a <code>LoginResponseState</code> instance, which uses the given connection for
57       * transmission.
58       * 
59       * @param initConnection The context connection, which is used for the network transmission.
60       * @param initNextStage The next stage to which should transfered to.
61       */
62      public LoginResponseState (final Connection initConnection, final LoginStage initNextStage) {
63  
64          super(initConnection);
65          nextStage = initNextStage;
66      }
67  
68      // --------------------------------------------------------------------------
69      // --------------------------------------------------------------------------
70  
71      /** {@inheritDoc} */
72      public final void execute () throws InternetSCSIException {
73  
74          ProtocolDataUnit protocolDataUnit;
75          final IDataSegment loginResponse = DataSegmentFactory.create(DataSegmentFormat.TEXT, connection.getSettingAsInt(OperationalTextKey.MAX_RECV_DATA_SEGMENT_LENGTH));
76  
77          do {
78              protocolDataUnit = connection.receive();
79  
80              if (!(protocolDataUnit.getBasicHeaderSegment().getParser() instanceof LoginResponseParser)) {
81                  break;
82              }
83  
84              loginResponse.append(protocolDataUnit.getDataSegment(), protocolDataUnit.getBasicHeaderSegment().getDataSegmentLength());
85          } while (!protocolDataUnit.getBasicHeaderSegment().isFinalFlag());
86          // extract Target Session Handle Identifying Handle
87          final LoginResponseParser parser = (LoginResponseParser) protocolDataUnit.getBasicHeaderSegment().getParser();
88          connection.getSession().setTargetSessionIdentifyingHandle(parser.getTargetSessionIdentifyingHandle());
89          // Set the Expected Status Sequence Number to the initial value received
90          // from the target. Then add the constant 2 to this value, because the
91          // incrementExpectedStatusSequence() method was already invoked.
92          connection.setExpectedStatusSequenceNumber(parser.getStatusSequenceNumber() + 1);// TODO was +2
93  
94          // check parameters....
95          LOGGER.info("Retrieving these login parameters:\n" + loginResponse.getSettings());
96  
97          connection.update(loginResponse.getSettings());
98  
99          LOGGER.info("Updated settings to these:\n" + connection.getSettings());
100         LOGGER.info("Nextstage is : " + nextStage);
101 
102         // is a transit to the next stage possible
103         if (protocolDataUnit.getBasicHeaderSegment().isFinalFlag()) {
104             if (nextStage == LoginStage.LOGIN_OPERATIONAL_NEGOTIATION) {
105                 connection.getSession().setPhase(new LoginOperationalNegotiationPhase());
106             } else if (nextStage == LoginStage.FULL_FEATURE_PHASE) {
107                 connection.getSession().setPhase(new FullFeaturePhase());
108                 // return false;
109             }
110         }
111 
112         // return true;
113     }
114 
115     // --------------------------------------------------------------------------
116     // --------------------------------------------------------------------------
117 
118     /** {@inheritDoc} */
119     @Override
120     public final Exception isCorrect (final ProtocolDataUnit protocolDataUnit) {
121 
122         if (protocolDataUnit.getBasicHeaderSegment().getParser() instanceof LoginResponseParser) {
123             return null;
124         } else {
125             return new IllegalStateException(new StringBuilder("Parser ").append(protocolDataUnit.getBasicHeaderSegment().getParser().toString()).append(" is instance of ").append(protocolDataUnit.getBasicHeaderSegment().getParser().getClass().toString()).append(" and not instance if LoginParser!").toString());
126         }
127 
128     }
129 
130     // --------------------------------------------------------------------------
131     // --------------------------------------------------------------------------
132     // --------------------------------------------------------------------------
133     // --------------------------------------------------------------------------
134 
135 }