1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
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
118
119
120
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
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 }