View Javadoc

1   /**
2    * Pyx4me framework
3    * Copyright (C) 2006-2008 pyx4j.com.
4    * 
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing,
12   * software distributed under the License is distributed on an
13   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14   * KIND, either express or implied.  See the License for the
15   * specific language governing permissions and limitations
16   * under the License.
17   * 
18   * @author vlads
19   * @version $Id: ObexBluetoothClient.java 2873 2008-12-27 00:57:36Z vlads $
20   */
21  package com.pyx4me.maven.obex;
22  
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.io.OutputStream;
27  import java.util.Iterator;
28  import java.util.List;
29  
30  import javax.bluetooth.LocalDevice;
31  import javax.microedition.io.Connector;
32  import javax.obex.ClientSession;
33  import javax.obex.HeaderSet;
34  import javax.obex.Operation;
35  import javax.obex.ResponseCodes;
36  
37  import org.apache.maven.plugin.MojoFailureException;
38  import org.apache.maven.plugin.logging.Log;
39  
40  public class ObexBluetoothClient {
41  
42  	private static class ConsoleProgressMonitor {
43  
44  		long total;
45  
46  		long startedTime;
47  
48  		long complete;
49  
50  		long printedTime;
51  
52  		static final long STEP_COUNT = 15;
53  
54  		static final long STEP_INTERVAL = 2 * 1000;
55  
56  		ConsoleProgressMonitor(long total) {
57  			this.startedTime = System.currentTimeMillis();
58  			this.complete = 0;
59  			this.total = total;
60  			this.printedTime = 0;
61  		}
62  
63  		void transferProgress(int sent) {
64  			this.complete += sent;
65  			long now = System.currentTimeMillis();
66  			if ((printedTime == 0) || ((now - printedTime) > STEP_INTERVAL)) {
67  				StringBuffer b = new StringBuffer();
68  				b.append("[INFO] Transferring: ");
69  				b.append(complete / 1024).append("/").append(total / 1024).append("K");
70  
71  				b.append(" [");
72  				for (int i = 0; i < STEP_COUNT; i++) {
73  					long eta = (i * total) / STEP_COUNT;
74  					if (eta > complete) {
75  						b.append(" ");
76  					} else {
77  						b.append(".");
78  					}
79  				}
80  				b.append("] ");
81  				b.append((long) (100 * complete / total)).append("%");
82  
83  				b.append("\r");
84  				System.out.print(b.toString());
85  				printedTime = now;
86  			}
87  		}
88  
89  		void transferComplete(Log log) {
90  			if (printedTime != 0) {
91  				long sec = (System.currentTimeMillis() - this.startedTime) / 1000;
92  				log.info("Transfer " + (total / 1024) + "K completed in " + sec + " sec                     ");
93  			}
94  		}
95  	}
96  
97  	public static void obexPut(List deployFiles, int connectionRetry, ServerConfig cfg, Log log) throws MojoFailureException {
98  		AbstractDeviceMojo.configureBlueCove(cfg, log);
99  		ClientSession clientSession = null;
100 		FileInputStream is = null;
101 		try {
102 			// System.setProperty("bluecove.debug", "true");
103 			String serverURL;
104 
105 			if (cfg.url.startsWith("tcpobex://")) {
106 				serverURL = cfg.url;
107 			} else if (cfg.url.startsWith("btgoep://")) {
108 				serverURL = cfg.url;
109 			} else {
110 				String url = cfg.url;
111 				if (url.indexOf(':') == -1) {
112 					url = ServiceSearchMojo.findOBEX(url, cfg.alias, log);
113 					if (url == null) {
114 						throw new MojoFailureException("OBEX Service not found");
115 					}
116 				} else if ("bluesoleil".equals(LocalDevice.getProperty("bluecove.stack"))) {
117 					// in BlueSoleil You need to run
118 					// DiscoveryAgent.searchServices() with UUID of your service
119 					// before you can make connection to it using
120 					// Connector.open("btspp://...");
121 					int portStart = url.indexOf(':');
122 					if (portStart != -1) {
123 						url = ServiceSearchMojo.findOBEX(url.substring(0, portStart), cfg.alias, log);
124 						if (url == null) {
125 							throw new MojoFailureException("OBEX Service not found");
126 						}
127 					}
128 				}
129 				serverURL = "btgoep://" + url;
130 			}
131 
132 			log.info(cfg.alias + " Connecting ...");
133 			int connectionOpenTry = 0;
134 			while (clientSession == null) {
135 				try {
136 					clientSession = (ClientSession) Connector.open(serverURL);
137 				} catch (IOException e) {
138 					connectionOpenTry++;
139 					if (connectionOpenTry > connectionRetry) {
140 						throw e;
141 					}
142 					Thread.sleep(500);
143 					log.warn(cfg.alias + " connection retry after error " + e.getMessage());
144 				}
145 			}
146 			HeaderSet hsc = clientSession.connect(clientSession.createHeaderSet());
147 			log.debug("connect responseCode " + hsc.getResponseCode());
148 			if (hsc.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
149                 log.error(cfg.alias + " invalid connect code " + hsc.getResponseCode());
150             }
151 			
152 			for (Iterator it = deployFiles.iterator(); it.hasNext();) {
153                 File file = (File) it.next();
154                 HeaderSet hsp = clientSession.createHeaderSet();
155                 hsp.setHeader(HeaderSet.NAME, file.getName());
156                 hsp.setHeader(HeaderSet.TYPE, ObexTypes.getObexFileType(file.getName()));
157                 long fileLength = file.length();
158                 hsp.setHeader(HeaderSet.LENGTH, new Long(fileLength));
159 
160                 log.info(cfg.alias + " Sending " + file.getName());
161                 Operation po = clientSession.put(hsp);
162 
163                 ConsoleProgressMonitor progress = new ConsoleProgressMonitor(fileLength);
164                 OutputStream os = po.openOutputStream();
165 
166                 is = new FileInputStream(file);
167                 byte[] buffer = new byte[0x400];
168                 int i = is.read(buffer);
169                 while (i != -1) {
170                     os.write(buffer, 0, i);
171 
172                     // Show progress
173                     progress.transferProgress(i);
174 
175                     i = is.read(buffer);
176                 }
177 
178                 os.close();
179 
180                 log.debug("put responseCode " + po.getResponseCode());
181 
182                 po.close();
183 
184                 progress.transferComplete(log);
185             }
186 
187 			HeaderSet hsd = clientSession.disconnect(null);
188 			log.debug("disconnect responseCode " + hsd.getResponseCode());
189 
190 			if (hsd.getResponseCode() == ResponseCodes.OBEX_HTTP_OK) {
191 				log.info(cfg.alias + " Finished successfully");
192 			}
193 
194 		} catch (IOException e) {
195 			log.error("Communication error", e);
196 			throw new MojoFailureException("Can't upload file");
197 		} catch (Throwable e) {
198 			log.error("Error", e);
199 			throw new MojoFailureException("Can't upload file");
200 		} finally {
201 			if (clientSession != null) {
202 				try {
203 					clientSession.close();
204 				} catch (IOException ignore) {
205 				}
206 			}
207 			if (is != null) {
208 				try {
209 					is.close();
210 				} catch (IOException ignore) {
211 				}
212 			}
213 			clientSession = null;
214 		}
215 	}
216 }