View Javadoc

1   /**
2    *  BlueCove - Java library for Bluetooth
3    *  Copyright (C) 2006-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: ObexBluetoothClient.java 2480 2008-12-03 06:45:29Z skarzhevskyy $
24   */
25  package net.sf.bluecove.obex;
26  
27  import java.io.ByteArrayInputStream;
28  import java.io.IOException;
29  import java.io.OutputStream;
30  import java.text.DecimalFormat;
31  
32  import javax.microedition.io.Connector;
33  import javax.obex.ClientSession;
34  import javax.obex.HeaderSet;
35  import javax.obex.Operation;
36  import javax.obex.ResponseCodes;
37  
38  import com.intel.bluetooth.obex.BlueCoveOBEX;
39  
40  /**
41   * 
42   */
43  public class ObexBluetoothClient {
44  
45  	private UserInteraction interaction;
46  
47  	private String fileName;
48  
49  	private byte[] data;
50  
51  	private class ProgressMonitor {
52  
53  	    int total;
54  
55          long startedTime;
56  
57          int complete;
58  
59          long printedTime;
60  
61          static final long STEP_COUNT = 15;
62  
63          static final long STEP_INTERVAL = 2 * 1000;
64  
65          DecimalFormat formater = new DecimalFormat("#,000");
66          
67          ProgressMonitor(int total) {
68              this.startedTime = System.currentTimeMillis();
69              this.complete = 0;
70              this.total = total;
71              this.printedTime = 0;
72              formater.setMaximumFractionDigits(0);
73          }
74  
75          void transferProgress(int sent) {
76              this.complete += sent;
77              interaction.setProgressValue(complete);
78              long now = System.currentTimeMillis();
79              if ((printedTime == 0) || ((now - printedTime) > STEP_INTERVAL)) {
80                  StringBuffer b = new StringBuffer();
81                  b.append("Transferring: ");
82                  b.append(formater.format(complete / 1024)).append("/").append(formater.format(total / 1024)).append("K ");
83                  b.append((long) (100 * complete / total)).append("% ");
84                  b.append(bps(total, now - this.startedTime));
85                  interaction.showStatus(b.toString());
86                  printedTime = now;
87              }
88          }
89  
90          void transferComplete(String message) {
91              if (printedTime != 0) {
92                  long msec = System.currentTimeMillis() - this.startedTime;
93                  String txt = message + " " + formater.format(total / 1024) + "K completed in " + (msec/1000) + " sec " + bps(total, msec);
94                  Logger.debug(txt);
95                  interaction.showStatus(txt);
96              }
97          }
98          
99          String bps(int size, long durationMsec) {
100             if (durationMsec == 0) {
101                 return "";
102             }
103             return formater.format((1000L * 8 * size) / durationMsec) + " bit/s";
104         }
105     }
106 
107 	
108 	public ObexBluetoothClient(UserInteraction interaction, String fileName, byte[] data) {
109 		super();
110 		this.interaction = interaction;
111 		this.fileName = fileName;
112 		this.data = data;
113 	}
114 
115 	public boolean obexPut(String serverURL) {
116 		ClientSession clientSession = null;
117 		ProgressMonitor progress = null;
118 		try {
119 			// System.setProperty("bluecove.debug", "true");
120 			Logger.debug("Connecting", serverURL);
121 			interaction.showStatus("Connecting ...");
122 			clientSession = (ClientSession) Connector.open(serverURL);
123 			HeaderSet hsConnectReply = clientSession.connect(clientSession.createHeaderSet());
124 			if (hsConnectReply.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
125 				interaction.showStatus("Connect Error " + hsConnectReply.getResponseCode());
126 			}
127 			
128 			Logger.debug("MTU selected " + BlueCoveOBEX.getPacketSize(clientSession));
129 			
130 			progress = new ProgressMonitor(data.length);
131 			
132 			HeaderSet hsOperation = clientSession.createHeaderSet();
133 			hsOperation.setHeader(HeaderSet.NAME, fileName);
134 			String type = ObexTypes.getObexFileType(fileName);
135 			if (type != null) {
136 				hsOperation.setHeader(HeaderSet.TYPE, type);
137 			}
138 			hsOperation.setHeader(HeaderSet.LENGTH, new Long(data.length));
139 
140 			interaction.setProgressMaximum(data.length);
141 			interaction.setProgressValue(0);
142 
143 			interaction.showStatus("Sending " + fileName + " ...");
144 			Operation po = clientSession.put(hsOperation);
145 
146 			OutputStream os = po.openOutputStream();
147 
148 			ByteArrayInputStream is = new ByteArrayInputStream(data);
149 			byte[] buffer = new byte[0x400];
150 			int i = is.read(buffer);
151 			while (i != -1) {
152 				os.write(buffer, 0, i);
153                 // Show progress
154                 progress.transferProgress(i);
155                 
156 				i = is.read(buffer);
157 			}
158 			os.flush();
159 			os.close();
160 
161 			// log.debug("put responseCode " + po.getResponseCode());
162 
163 			po.close();
164 
165 			interaction.setProgressDone();
166 
167 			HeaderSet hsDisconnect = clientSession.disconnect(null);
168 			// log.debug("disconnect responseCode " + hs.getResponseCode());
169 
170 			if (hsDisconnect.getResponseCode() == ResponseCodes.OBEX_HTTP_OK) {
171 			    progress.transferComplete("Success");
172 				return true;
173 			} else {
174 			    progress.transferComplete("Code " + hsDisconnect.getResponseCode());
175 				return false;
176 			}
177 
178 		} catch (IOException e) {
179 			Logger.error(e);
180 			interaction.showStatus("Communication error " + e.getMessage());
181 			return false;
182 		} catch (Throwable e) {
183 			Logger.error(e);
184 			interaction.showStatus("Error " + e.getMessage());
185 			return false;
186 		} finally {
187 			if (clientSession != null) {
188 				try {
189 					clientSession.close();
190 				} catch (IOException ignore) {
191 				}
192 			}
193 			clientSession = null;
194 			interaction.setProgressValue(0);
195 		}
196 	}
197 
198 }