/**
* BlueCove - Java library for Bluetooth
* Copyright (C) 2006-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 net.sf.bluecove.obex;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import javax.microedition.io.Connector;
import javax.obex.ClientSession;
import javax.obex.HeaderSet;
import javax.obex.Operation;
import javax.obex.ResponseCodes;
import com.intel.bluetooth.obex.BlueCoveOBEX;
/**
*
*/
public class ObexBluetoothClient {
private UserInteraction interaction;
private String fileName;
private byte[] data;
private class ProgressMonitor {
int total;
long startedTime;
int complete;
long printedTime;
static final long STEP_COUNT = 15;
static final long STEP_INTERVAL = 2 * 1000;
DecimalFormat formater = new DecimalFormat("#,000");
ProgressMonitor(int total) {
this.startedTime = System.currentTimeMillis();
this.complete = 0;
this.total = total;
this.printedTime = 0;
formater.setMaximumFractionDigits(0);
}
void transferProgress(int sent) {
this.complete += sent;
interaction.setProgressValue(complete);
long now = System.currentTimeMillis();
if ((printedTime == 0) || ((now - printedTime) > STEP_INTERVAL)) {
StringBuffer b = new StringBuffer();
b.append("Transferring: ");
b.append(formater.format(complete / 1024)).append("/").append(formater.format(total / 1024)).append("K ");
b.append((long) (100 * complete / total)).append("% ");
b.append(bps(total, now - this.startedTime));
interaction.showStatus(b.toString());
printedTime = now;
}
}
void transferComplete(String message) {
if (printedTime != 0) {
long msec = System.currentTimeMillis() - this.startedTime;
String txt = message + " " + formater.format(total / 1024) + "K completed in " + (msec/1000) + " sec " + bps(total, msec);
Logger.debug(txt);
interaction.showStatus(txt);
}
}
String bps(int size, long durationMsec) {
if (durationMsec == 0) {
return "";
}
return formater.format((1000L * 8 * size) / durationMsec) + " bit/s";
}
}
public ObexBluetoothClient(UserInteraction interaction, String fileName, byte[] data) {
super();
this.interaction = interaction;
this.fileName = fileName;
this.data = data;
}
public boolean obexPut(String serverURL) {
ClientSession clientSession = null;
ProgressMonitor progress = null;
try {
// System.setProperty("bluecove.debug", "true");
Logger.debug("Connecting", serverURL);
interaction.showStatus("Connecting ...");
clientSession = (ClientSession) Connector.open(serverURL);
HeaderSet hsConnectReply = clientSession.connect(clientSession.createHeaderSet());
if (hsConnectReply.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
interaction.showStatus("Connect Error " + hsConnectReply.getResponseCode());
}
Logger.debug("MTU selected " + BlueCoveOBEX.getPacketSize(clientSession));
progress = new ProgressMonitor(data.length);
HeaderSet hsOperation = clientSession.createHeaderSet();
hsOperation.setHeader(HeaderSet.NAME, fileName);
String type = ObexTypes.getObexFileType(fileName);
if (type != null) {
hsOperation.setHeader(HeaderSet.TYPE, type);
}
hsOperation.setHeader(HeaderSet.LENGTH, new Long(data.length));
interaction.setProgressMaximum(data.length);
interaction.setProgressValue(0);
interaction.showStatus("Sending " + fileName + " ...");
Operation po = clientSession.put(hsOperation);
OutputStream os = po.openOutputStream();
ByteArrayInputStream is = new ByteArrayInputStream(data);
byte[] buffer = new byte[0x400];
int i = is.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
// Show progress
progress.transferProgress(i);
i = is.read(buffer);
}
os.flush();
os.close();
// log.debug("put responseCode " + po.getResponseCode());
po.close();
interaction.setProgressDone();
HeaderSet hsDisconnect = clientSession.disconnect(null);
// log.debug("disconnect responseCode " + hs.getResponseCode());
if (hsDisconnect.getResponseCode() == ResponseCodes.OBEX_HTTP_OK) {
progress.transferComplete("Success");
return true;
} else {
progress.transferComplete("Code " + hsDisconnect.getResponseCode());
return false;
}
} catch (IOException e) {
Logger.error(e);
interaction.showStatus("Communication error " + e.getMessage());
return false;
} catch (Throwable e) {
Logger.error(e);
interaction.showStatus("Error " + e.getMessage());
return false;
} finally {
if (clientSession != null) {
try {
clientSession.close();
} catch (IOException ignore) {
}
}
clientSession = null;
interaction.setProgressValue(0);
}
}
}