View Javadoc

1   /**
2    *  BlueCove - Java library for Bluetooth
3    *  Copyright (C) 2007-2008 Vlad Skarzhevskyy
4    *
5    *  This library is free software; you can redistribute it and/or
6    *  modify it under the terms of the GNU Lesser General Public
7    *  License as published by the Free Software Foundation; either
8    *  version 2.1 of the License, or (at your option) any later version.
9    *
10   *  This library is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   *  Lesser General Public License for more details.
14   *
15   *  You should have received a copy of the GNU Lesser General Public
16   *  License along with this library; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   *
19   *  @version $Id: OBEXServerOperationGet.java 2364 2008-07-21 14:49:42Z skarzhevskyy $
20   */
21  package com.intel.bluetooth.obex;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.OutputStream;
26  
27  import javax.obex.HeaderSet;
28  import javax.obex.ResponseCodes;
29  
30  import com.intel.bluetooth.DebugLog;
31  
32  /**
33   * @author vlads
34   * 
35   */
36  class OBEXServerOperationGet extends OBEXServerOperation implements OBEXOperationDelivery, OBEXOperationReceive {
37  
38  	protected OBEXServerOperationGet(OBEXServerSessionImpl session, HeaderSet receivedHeaders, boolean finalPacket)
39  			throws IOException {
40  		super(session, receivedHeaders);
41  		if (finalPacket) {
42  			requestEnded = true;
43  		}
44  		this.inputStream = new OBEXOperationInputStream(this);
45  		processIncommingData(receivedHeaders, finalPacket);
46  	}
47  
48  	/*
49  	 * (non-Javadoc)
50  	 * 
51  	 * @see javax.microedition.io.InputConnection#openInputStream()
52  	 */
53  	public InputStream openInputStream() throws IOException {
54  		if (isClosed) {
55  			throw new IOException("operation closed");
56  		}
57  		if (inputStreamOpened) {
58  			throw new IOException("input stream already open");
59  		}
60  		this.inputStreamOpened = true;
61  		return this.inputStream;
62  	}
63  
64  	/*
65  	 * (non-Javadoc)
66  	 * 
67  	 * @see javax.microedition.io.OutputConnection#openOutputStream()
68  	 */
69  	public OutputStream openOutputStream() throws IOException {
70  		if (isClosed) {
71  			throw new IOException("operation closed");
72  		}
73  		if (outputStream != null) {
74  			throw new IOException("output stream already open");
75  		}
76  		requestEnded = true;
77  		outputStream = new OBEXOperationOutputStream(session.mtu, this);
78  		session.writeOperation(OBEXOperationCodes.OBEX_RESPONSE_CONTINUE, OBEXHeaderSetImpl.toByteArray(sendHeaders));
79  		sendHeaders = null;
80  		return outputStream;
81  	}
82  
83  	/*
84  	 * (non-Javadoc)
85  	 * 
86  	 * @see javax.microedition.io.Connection#close()
87  	 */
88  	public void close() throws IOException {
89  		if (outputStream != null) {
90  			outputStream.close();
91  			outputStream = null;
92  		}
93  		inputStream.close();
94  		super.close();
95  	}
96  
97  	protected boolean readRequestPacket() throws IOException {
98  		byte[] b = session.readOperation();
99  		int opcode = b[0] & 0xFF;
100 		boolean finalPacket = ((opcode & OBEXOperationCodes.FINAL_BIT) != 0);
101 		if (finalPacket) {
102 			DebugLog.debug("server operation got final packet");
103 			finalPacketReceived = true;
104 		}
105 		switch (opcode) {
106 		case OBEXOperationCodes.GET_FINAL:
107 		case OBEXOperationCodes.GET:
108 			if (finalPacket) {
109 				requestEnded = true;
110 			}
111 			HeaderSet requestHeaders = OBEXHeaderSetImpl.readHeaders(b[0], b, 3);
112 			OBEXHeaderSetImpl.appendHeaders(this.receivedHeaders, requestHeaders);
113 			processIncommingData(requestHeaders, finalPacket);
114 			break;
115 		case OBEXOperationCodes.ABORT:
116 			processAbort();
117 			break;
118 		default:
119 			errorReceived = true;
120 			DebugLog.debug0x("server operation invalid request", OBEXUtils.toStringObexResponseCodes(opcode), opcode);
121 			session.writeOperation(ResponseCodes.OBEX_HTTP_BAD_REQUEST, null);
122 		}
123 		return finalPacket;
124 	}
125 
126 	/*
127 	 * (non-Javadoc)
128 	 * 
129 	 * @see com.intel.bluetooth.obex.OBEXOperationReceive#receiveData(com.intel.bluetooth.obex.OBEXOperationInputStream)
130 	 */
131 	public void receiveData(OBEXOperationInputStream is) throws IOException {
132 		if (requestEnded || errorReceived) {
133 			this.inputStream.appendData(null, true);
134 			return;
135 		}
136 		DebugLog.debug("server operation reply continue");
137 		session.writeOperation(OBEXOperationCodes.OBEX_RESPONSE_CONTINUE, OBEXHeaderSetImpl.toByteArray(sendHeaders));
138 		sendHeaders = null;
139 		readRequestPacket();
140 	}
141 
142 	/*
143 	 * (non-Javadoc)
144 	 * 
145 	 * @see com.intel.bluetooth.obex.OBEXOperationDelivery#deliverPacket(boolean,
146 	 *      byte[])
147 	 */
148 	public void deliverPacket(boolean finalPacket, byte[] buffer) throws IOException {
149 		HeaderSet dataHeaders = OBEXSessionBase.createOBEXHeaderSet();
150 		int opcode = OBEXOperationCodes.OBEX_RESPONSE_CONTINUE;
151 		int dataHeaderID = OBEXHeaderSetImpl.OBEX_HDR_BODY;
152 		if (finalPacket) {
153 			// opcode = OBEXOperationCodes.OBEX_RESPONSE_SUCCESS;
154 			dataHeaderID = OBEXHeaderSetImpl.OBEX_HDR_BODY_END;
155 		}
156 		dataHeaders.setHeader(dataHeaderID, buffer);
157 		if (sendHeaders != null) {
158 			OBEXHeaderSetImpl.appendHeaders(dataHeaders, sendHeaders);
159 			sendHeaders = null;
160 		}
161 		session.writeOperation(opcode, OBEXHeaderSetImpl.toByteArray(dataHeaders));
162 		readRequestPacket();
163 	}
164 
165 	private void processAbort() throws IOException {
166 		// TODO proper abort + UnitTests
167 		finalPacketReceived = true;
168 		requestEnded = true;
169 		session.writeOperation(OBEXOperationCodes.OBEX_RESPONSE_SUCCESS, null);
170 		throw new IOException("Operation aborted");
171 	}
172 
173 }