View Javadoc

1   /**
2    *  BlueCove - Java library for Bluetooth
3    *  Copyright (C) 2007-2008 Vlad Skarzhevskyy
4    *
5    *  Licensed to the Apache Software Foundation (ASF) under one
6    *  or more contributor license agreements.  See the NOTICE file
7    *  distributed with this work for additional information
8    *  regarding copyright ownership.  The ASF licenses this file
9    *  to you under the Apache License, Version 2.0 (the
10   *  "License"); you may not use this file except in compliance
11   *  with the License.  You may obtain a copy of the License at
12   *
13   *    http://www.apache.org/licenses/LICENSE-2.0
14   *
15   *  Unless required by applicable law or agreed to in writing,
16   *  software distributed under the License is distributed on an
17   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   *  KIND, either express or implied.  See the License for the
19   *  specific language governing permissions and limitations
20   *  under the License.
21   *
22   *  @author vlads
23   *  @version $Id: OBEXServerOperationPut.java 2643 2008-12-23 00:24:46Z skarzhevskyy $
24   */
25  package com.intel.bluetooth.obex;
26  
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.io.OutputStream;
30  
31  import javax.obex.ResponseCodes;
32  
33  import com.intel.bluetooth.DebugLog;
34  
35  class OBEXServerOperationPut extends OBEXServerOperation implements OBEXOperationReceive, OBEXOperationDelivery {
36  
37  	protected OBEXServerOperationPut(OBEXServerSessionImpl session, OBEXHeaderSetImpl receivedHeaders,
38  			boolean finalPacket) throws IOException {
39  		super(session, receivedHeaders);
40  		this.inputStream = new OBEXOperationInputStream(this);
41  		processIncommingData(receivedHeaders, finalPacket);
42  	}
43  
44  	/*
45  	 * (non-Javadoc)
46  	 * 
47  	 * @see javax.microedition.io.InputConnection#openInputStream()
48  	 */
49  	public InputStream openInputStream() throws IOException {
50  		if (isClosed) {
51  			throw new IOException("operation closed");
52  		}
53  		if (inputStreamOpened) {
54  			throw new IOException("input stream already open");
55  		}
56  		DebugLog.debug("openInputStream");
57  		inputStreamOpened = true;
58  		return inputStream;
59  	}
60  
61  	/*
62  	 * (non-Javadoc)
63  	 * 
64  	 * @see javax.microedition.io.OutputConnection#openOutputStream()
65  	 */
66  	public OutputStream openOutputStream() throws IOException {
67  		if (isClosed) {
68  			throw new IOException("operation closed");
69  		}
70  		if (outputStream != null) {
71  			throw new IOException("output stream already open");
72  		}
73  		outputStream = new OBEXOperationOutputStream(session.mtu, this);
74  		return outputStream;
75  	}
76  
77  	/*
78  	 * (non-Javadoc)
79  	 * 
80  	 * @see javax.microedition.io.Connection#close()
81  	 */
82  	public void close() throws IOException {
83  		DebugLog.debug("server close put operation");
84  		if (inputStream != null) {
85  			inputStream.close();
86  			inputStream = null;
87  		}
88  		if (outputStream != null) {
89  			outputStream.close();
90  			outputStream = null;
91  		}
92  		super.close();
93  	}
94  
95  	protected boolean readRequestPacket() throws IOException {
96  		byte[] b = session.readPacket();
97  		int opcode = b[0] & 0xFF;
98  		boolean finalPacket = ((opcode & OBEXOperationCodes.FINAL_BIT) != 0);
99  		if (finalPacket) {
100 			DebugLog.debug("server operation got final packet");
101 			finalPacketReceived = true;
102 		}
103 		switch (opcode) {
104 		case OBEXOperationCodes.PUT_FINAL:
105 		case OBEXOperationCodes.PUT:
106 			OBEXHeaderSetImpl requestHeaders = OBEXHeaderSetImpl.readHeaders(b[0], b, 3);
107 			if (!session.handleAuthenticationResponse(requestHeaders)) {
108 				errorReceived = true;
109 				session.writePacket(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null);
110 			} else {
111 				OBEXHeaderSetImpl.appendHeaders(this.receivedHeaders, requestHeaders);
112 				processIncommingData(requestHeaders, finalPacket);
113 			}
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.writePacket(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 (finalPacketReceived || errorReceived) {
133 			is.appendData(null, true);
134 			return;
135 		}
136 		DebugLog.debug("server operation reply continue");
137 		session.writePacket(OBEXOperationCodes.OBEX_RESPONSE_CONTINUE, sendHeaders);
138 		sendHeaders = null;
139 		readRequestPacket();
140 	}
141 
142 	/*
143 	 * (non-Javadoc)
144 	 * 
145 	 * @see com.intel.bluetooth.obex.OBEXOperationDelivery#deliverPacket(boolean, byte[])
146 	 */
147 	public void deliverPacket(boolean finalPacket, byte[] buffer) throws IOException {
148 		if (session.requestSent) {
149 			// TODO Consider moving readRequestPacket() to the begging of the function
150 			readRequestPacket();
151 			if (session.requestSent) {
152 				throw new IOException("Client not requesting data");
153 			}
154 		}
155 		OBEXHeaderSetImpl dataHeaders = OBEXSessionBase.createOBEXHeaderSetImpl();
156 		int opcode = OBEXOperationCodes.OBEX_RESPONSE_CONTINUE;
157 		int dataHeaderID = OBEXHeaderSetImpl.OBEX_HDR_BODY;
158 		if (finalPacket) {
159 			// opcode = OBEXOperationCodes.OBEX_RESPONSE_SUCCESS;
160 			dataHeaderID = OBEXHeaderSetImpl.OBEX_HDR_BODY_END;
161 		}
162 		dataHeaders.setHeader(dataHeaderID, buffer);
163 		if (sendHeaders != null) {
164 			OBEXHeaderSetImpl.appendHeaders(dataHeaders, sendHeaders);
165 			sendHeaders = null;
166 		}
167 		session.writePacket(opcode, dataHeaders);
168 		readRequestPacket();
169 	}
170 
171 	private void processAbort() throws IOException {
172 		isAborted = true;
173 		session.writePacket(OBEXOperationCodes.OBEX_RESPONSE_SUCCESS, null);
174 		close();
175 		throw new IOException("Operation aborted by client");
176 	}
177 
178 }