com.intel.bluetooth.obex.OBEXSessionBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bluecove Show documentation
Show all versions of bluecove Show documentation
BlueCove is JSR-82 J2SE implementation that currently interfaces with the Mac OS X, WIDCOMM, BlueSoleil and Microsoft Bluetooth stack
The newest version!
/**
* BlueCove - Java library for Bluetooth
* Copyright (C) 2007-2008 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: OBEXSessionBase.java 2641 2008-12-22 23:28:52Z skarzhevskyy $
*/
package com.intel.bluetooth.obex;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Vector;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.microedition.io.Connection;
import javax.microedition.io.StreamConnection;
import javax.obex.Authenticator;
import javax.obex.HeaderSet;
import javax.obex.ServerRequestHandler;
import com.intel.bluetooth.BluetoothConnectionAccess;
import com.intel.bluetooth.BluetoothStack;
import com.intel.bluetooth.DebugLog;
import com.intel.bluetooth.obex.OBEXAuthentication.Challenge;
/**
* Base for Client and Server implementations. See Bluetooth Specification Documents for
* details.
*
*/
abstract class OBEXSessionBase implements Connection, BluetoothConnectionAccess {
protected boolean isConnected;
private StreamConnection conn;
private InputStream is;
private OutputStream os;
protected long connectionID;
protected int mtu = OBEXOperationCodes.OBEX_DEFAULT_MTU;
protected Authenticator authenticator;
protected OBEXConnectionParams obexConnectionParams;
protected int packetsCountWrite;
protected int packetsCountRead;
private Vector authChallengesSent;
/**
* Each request packet flowed by response. This flag is from Client point of view
*/
protected boolean requestSent;
public OBEXSessionBase(StreamConnection conn, OBEXConnectionParams obexConnectionParams) throws IOException {
if (obexConnectionParams == null) {
throw new NullPointerException("obexConnectionParams is null");
}
this.isConnected = false;
this.conn = conn;
this.obexConnectionParams = obexConnectionParams;
this.mtu = obexConnectionParams.mtu;
this.connectionID = -1;
this.packetsCountWrite = 0;
this.packetsCountRead = 0;
boolean initOK = false;
try {
this.os = conn.openOutputStream();
this.is = conn.openInputStream();
initOK = true;
} finally {
if (!initOK) {
try {
this.close();
} catch (IOException e) {
DebugLog.error("close error", e);
}
}
}
}
public void close() throws IOException {
StreamConnection c = this.conn;
this.conn = null;
try {
if (this.is != null) {
this.is.close();
this.is = null;
}
if (this.os != null) {
this.os.close();
this.os = null;
}
} finally {
if (c != null) {
c.close();
}
}
}
static OBEXHeaderSetImpl createOBEXHeaderSetImpl() {
return new OBEXHeaderSetImpl();
}
public static HeaderSet createOBEXHeaderSet() {
return createOBEXHeaderSetImpl();
}
static void validateCreatedHeaderSet(HeaderSet headers) {
OBEXHeaderSetImpl.validateCreatedHeaderSet(headers);
}
protected void writePacket(int commId, OBEXHeaderSetImpl headers) throws IOException {
writePacketWithFlags(commId, null, headers);
}
protected synchronized void writePacketWithFlags(int commId, byte[] headerFlagsData, OBEXHeaderSetImpl headers)
throws IOException {
if (this.requestSent) {
throw new IOException("Write packet out of order");
}
this.requestSent = true;
int len = 3;
if (this.connectionID != -1) {
len += 5;
}
if (headerFlagsData != null) {
len += headerFlagsData.length;
}
byte[] data = null;
if (headers != null) {
data = OBEXHeaderSetImpl.toByteArray(headers);
len += data.length;
}
if (len > mtu) {
throw new IOException("Can't sent more data than in MTU, len=" + len + ", mtu=" + mtu);
}
this.packetsCountWrite++;
ByteArrayOutputStream buf = new ByteArrayOutputStream();
OBEXHeaderSetImpl.writeObexLen(buf, commId, len);
if (headerFlagsData != null) {
buf.write(headerFlagsData);
}
if (this.connectionID != -1) {
OBEXHeaderSetImpl.writeObexInt(buf, OBEXHeaderSetImpl.OBEX_HDR_CONNECTION, this.connectionID);
}
if (data != null) {
buf.write(data);
}
DebugLog.debug0x("obex send (" + this.packetsCountWrite + ")", OBEXUtils.toStringObexResponseCodes(commId),
commId);
os.write(buf.toByteArray());
os.flush();
DebugLog.debug("obex sent (" + this.packetsCountWrite + ") len", len);
if ((headers != null) && (headers.hasAuthenticationChallenge())) {
if (authChallengesSent == null) {
authChallengesSent = new Vector();
}
for (Enumeration iter = headers.getAuthenticationChallenges(); iter.hasMoreElements();) {
byte[] authChallenge = (byte[]) iter.nextElement();
Challenge challenge = new Challenge(authChallenge);
authChallengesSent.addElement(challenge);
}
}
}
protected synchronized byte[] readPacket() throws IOException {
if (!this.requestSent) {
throw new IOException("Read packet out of order");
}
this.requestSent = false;
byte[] header = new byte[3];
OBEXUtils.readFully(is, obexConnectionParams, header);
this.packetsCountRead++;
DebugLog.debug0x("obex received (" + this.packetsCountRead + ")", OBEXUtils
.toStringObexResponseCodes(header[0]), header[0] & 0xFF);
int lenght = OBEXUtils.bytesToShort(header[1], header[2]);
if (lenght == 3) {
return header;
}
if ((lenght < 3) || (lenght > OBEXOperationCodes.OBEX_MAX_PACKET_LEN)) {
throw new IOException("Invalid packet length " + lenght);
}
byte[] data = new byte[lenght];
System.arraycopy(header, 0, data, 0, header.length);
OBEXUtils.readFully(is, obexConnectionParams, data, header.length, lenght - header.length);
if (is.available() > 0) {
DebugLog.debug("has more data after read", is.available());
}
return data;
}
private void validateBluetoothConnection() {
if ((conn != null) && !(conn instanceof BluetoothConnectionAccess)) {
throw new IllegalArgumentException("Not a Bluetooth connection " + conn.getClass().getName());
}
}
void validateAuthenticationResponse(OBEXHeaderSetImpl requestHeaders, OBEXHeaderSetImpl incomingHeaders)
throws IOException {
if ((requestHeaders != null) && requestHeaders.hasAuthenticationChallenge()
&& (!incomingHeaders.hasAuthenticationResponses())) {
// TODO verify that this appropriate Exception
throw new IOException("Authentication response is missing");
}
handleAuthenticationResponse(incomingHeaders, null);
}
boolean handleAuthenticationResponse(OBEXHeaderSetImpl incomingHeaders, ServerRequestHandler serverHandler)
throws IOException {
if (incomingHeaders.hasAuthenticationResponses()) {
if (authenticator == null) {
throw new IOException("Authenticator required for authentication");
}
if ((authChallengesSent == null) && (authChallengesSent.size() == 0)) {
throw new IOException("Authentication challenges had not been sent");
}
boolean authenticated = false;
try {
authenticated = OBEXAuthentication.handleAuthenticationResponse(incomingHeaders, authenticator,
serverHandler, authChallengesSent);
} finally {
if ((authenticated) && (authChallengesSent != null)) {
authChallengesSent.removeAllElements();
}
}
return authenticated;
} else {
if ((authChallengesSent != null) && (authChallengesSent.size() > 0)) {
throw new IOException("Authentication response is missing");
}
return true;
}
}
void handleAuthenticationChallenge(OBEXHeaderSetImpl incomingHeaders, OBEXHeaderSetImpl replyHeaders)
throws IOException {
if (incomingHeaders.hasAuthenticationChallenge()) {
if (authenticator == null) {
throw new IOException("Authenticator required for authentication");
}
OBEXAuthentication.handleAuthenticationChallenge(incomingHeaders, replyHeaders, authenticator);
}
}
/*
* (non-Javadoc)
*
* @see com.intel.bluetooth.BluetoothConnectionAccess#getRemoteAddress()
*/
public long getRemoteAddress() throws IOException {
validateBluetoothConnection();
if (conn == null) {
throw new IOException("Connection closed");
}
return ((BluetoothConnectionAccess) conn).getRemoteAddress();
}
/*
* (non-Javadoc)
*
* @see com.intel.bluetooth.BluetoothConnectionAccess#getRemoteDevice()
*/
public RemoteDevice getRemoteDevice() {
validateBluetoothConnection();
if (conn == null) {
return null;
}
return ((BluetoothConnectionAccess) conn).getRemoteDevice();
}
/*
* (non-Javadoc)
*
* @see com.intel.bluetooth.BluetoothConnectionAccess#isClosed()
*/
public boolean isClosed() {
if (conn == null) {
return true;
}
if (this.conn instanceof BluetoothConnectionAccess) {
return ((BluetoothConnectionAccess) conn).isClosed();
} else {
return false;
}
}
/*
* (non-Javadoc)
*
* @see com.intel.bluetooth.BluetoothConnectionAccess#shutdown()
*/
public void shutdown() throws IOException {
if (this.conn instanceof BluetoothConnectionAccess) {
((BluetoothConnectionAccess) conn).shutdown();
}
}
/*
* (non-Javadoc)
*
* @see com.intel.bluetooth.BluetoothConnectionAccess#markAuthenticated()
*/
public void markAuthenticated() {
validateBluetoothConnection();
if (conn != null) {
((BluetoothConnectionAccess) conn).markAuthenticated();
}
}
/*
* (non-Javadoc)
*
* @see com.intel.bluetooth.BluetoothConnectionAccess#getSecurityOpt()
*/
public int getSecurityOpt() {
validateBluetoothConnection();
if (conn == null) {
return ServiceRecord.NOAUTHENTICATE_NOENCRYPT;
} else {
return ((BluetoothConnectionAccess) conn).getSecurityOpt();
}
}
/*
* (non-Javadoc)
*
* @see com.intel.bluetooth.BluetoothConnectionAccess#encrypt(boolean)
*/
public boolean encrypt(long address, boolean on) throws IOException {
validateBluetoothConnection();
if (conn == null) {
throw new IOException("Connection closed");
}
return ((BluetoothConnectionAccess) conn).encrypt(address, on);
}
/*
* (non-Javadoc)
*
* @see com.intel.bluetooth.BluetoothConnectionAccess#setRemoteDevice(javax.bluetooth .RemoteDevice)
*/
public void setRemoteDevice(RemoteDevice remoteDevice) {
validateBluetoothConnection();
if (conn != null) {
((BluetoothConnectionAccess) conn).setRemoteDevice(remoteDevice);
}
}
/*
* (non-Javadoc)
*
* @see com.intel.bluetooth.BluetoothConnectionAccess#getBluetoothStack()
*/
public BluetoothStack getBluetoothStack() {
validateBluetoothConnection();
if (conn == null) {
return null;
}
return ((BluetoothConnectionAccess) conn).getBluetoothStack();
}
/**
* Function used in unit tests.
*
* @return the packetsCountWrite
*/
int getPacketsCountWrite() {
return this.packetsCountWrite;
}
/**
* Function used in unit tests.
*
* @return the packetsCountRead
*/
int getPacketsCountRead() {
return this.packetsCountRead;
}
/**
* Function used in unit tests.
*
* @return the mtu
*/
int getPacketSize() {
return this.mtu;
}
/**
* Function used to change the connection mtu
*
* @param mtu
* @throws IOException
*/
void setPacketSize(int mtu) throws IOException {
if (isConnected) {
throw new IOException("Session already connected");
}
obexConnectionParams.mtu = mtu;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy