/** * BlueCove - Java library for Bluetooth * Copyright (C) 2007-2009 Vlad Skarzhevskyy * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * @author vlads * @version $Id$ */ package com.intel.bluetooth.obex; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import javax.obex.HeaderSet; import javax.obex.Operation; import javax.obex.ResponseCodes; import com.intel.bluetooth.DebugLog; abstract class OBEXServerOperation implements Operation, OBEXOperation { protected OBEXServerSessionImpl session; protected HeaderSet receivedHeaders; protected OBEXHeaderSetImpl sendHeaders; protected boolean isClosed = false; protected boolean isAborted = false; protected boolean finalPacketReceived = false; protected boolean requestEnded = false; protected boolean errorReceived = false; protected boolean incommingDataReceived = false; protected OBEXOperationOutputStream outputStream; protected boolean outputStreamOpened = false; protected OBEXOperationInputStream inputStream; protected boolean inputStreamOpened = false; protected OBEXServerOperation(OBEXServerSessionImpl session, OBEXHeaderSetImpl receivedHeaders) throws IOException { this.session = session; this.receivedHeaders = receivedHeaders; if (receivedHeaders.hasAuthenticationChallenge()) { sendHeaders = OBEXSessionBase.createOBEXHeaderSetImpl(); this.session.handleAuthenticationChallenge(receivedHeaders, sendHeaders); } } boolean exchangeRequestPhasePackets() throws IOException { session.writePacket(OBEXOperationCodes.OBEX_RESPONSE_CONTINUE, null); return readRequestPacket(); } protected abstract boolean readRequestPacket() throws IOException; void writeResponse(int responseCode) throws IOException { DebugLog.debug0x("server operation reply final", responseCode); session.writePacket(responseCode, sendHeaders); sendHeaders = null; if (responseCode == ResponseCodes.OBEX_HTTP_OK) { while ((!finalPacketReceived) && (!session.isClosed())) { DebugLog.debug("server waits to receive final packet"); readRequestPacket(); if (!errorReceived) { session.writePacket(responseCode, null); } } } else { DebugLog.debug("sent final reply"); } } protected void processIncommingData(HeaderSet dataHeaders, boolean eof) throws IOException { // If this operation closing if (this.inputStream == null) { return; } byte[] data = (byte[]) dataHeaders.getHeader(OBEXHeaderSetImpl.OBEX_HDR_BODY); if (data == null) { data = (byte[]) dataHeaders.getHeader(OBEXHeaderSetImpl.OBEX_HDR_BODY_END); if (data != null) { eof = true; } } if (data != null) { incommingDataReceived = true; DebugLog.debug("server received Data eof: " + eof + " len:", data.length); inputStream.appendData(data, eof); } else if (eof) { inputStream.appendData(null, eof); } } /* * (non-Javadoc) * * @see javax.obex.Operation#abort() */ public void abort() throws IOException { throw new IOException("Can't abort server operation"); } /* * (non-Javadoc) * * @see javax.obex.Operation#getReceivedHeaders() */ public HeaderSet getReceivedHeaders() throws IOException { return OBEXHeaderSetImpl.cloneHeaders(receivedHeaders); } /* * (non-Javadoc) * * @see javax.obex.Operation#getResponseCode() */ public int getResponseCode() throws IOException { throw new IOException("Operation object was created by an OBEX server"); } /* * (non-Javadoc) * * @see javax.obex.Operation#sendHeaders(javax.obex.HeaderSet) */ public void sendHeaders(HeaderSet headers) throws IOException { if (headers == null) { throw new NullPointerException("headers are null"); } OBEXHeaderSetImpl.validateCreatedHeaderSet(headers); if (isClosed) { throw new IOException("operation closed"); } if (sendHeaders != null) { OBEXHeaderSetImpl.appendHeaders(sendHeaders, headers); } else { sendHeaders = (OBEXHeaderSetImpl) headers; } } /* * (non-Javadoc) * * @see javax.microedition.io.ContentConnection#getEncoding() <code>getEncoding()</code> will always return * <code>null</code> */ public String getEncoding() { return null; } /* * (non-Javadoc) * * @see javax.microedition.io.ContentConnection#getLength() <code>getLength()</code> will return the length * specified by the OBEX Length header or -1 if the OBEX Length header was not included. */ public long getLength() { Long len; try { len = (Long) receivedHeaders.getHeader(HeaderSet.LENGTH); } catch (IOException e) { return -1; } if (len == null) { return -1; } return len.longValue(); } /* * (non-Javadoc) * * @see javax.microedition.io.ContentConnection#getType() <code>getType()</code> will return the value specified in * the OBEX Type header or <code>null</code> if the OBEX Type header was not included. */ public String getType() { try { return (String) receivedHeaders.getHeader(HeaderSet.TYPE); } catch (IOException e) { return null; } } /* * (non-Javadoc) * * @see javax.microedition.io.InputConnection#openDataInputStream() */ public DataInputStream openDataInputStream() throws IOException { return new DataInputStream(openInputStream()); } /* * (non-Javadoc) * * @see javax.microedition.io.OutputConnection#openDataOutputStream() */ public DataOutputStream openDataOutputStream() throws IOException { return new DataOutputStream(openOutputStream()); } /* * (non-Javadoc) * * @see javax.microedition.io.Connection#close() */ public void close() throws IOException { this.isClosed = true; } public boolean isClosed() { return this.isClosed; } public boolean isIncommingDataReceived() { return this.incommingDataReceived; } public boolean isErrorReceived() { return this.errorReceived; } }