/* * Copyright 2010 Google Inc. * * Licensed 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 */ package com.allthingsgeek.celljoust; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; import java.util.Set; import java.util.UUID; import com.cellbots.CellbotProtos.ControllerState; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; class BTCommThread extends Thread { private BluetoothSocket socket; private InputStream istream; private OutputStream ostream; private BluetoothAdapter adapter; StringBuffer sb; byte[] prevBuffer; // buffer store // for // the stream BluetoothDevice device; int bytes; // bytes // returned // from read() RobotStateHandler state; public Handler handler; public StringBuffer readBuffer; public static String TAG = "BtCommThread"; private Boolean lastMsgWasAllZeros = false; public BTCommThread(BluetoothAdapter adapter, RobotStateHandler rState) { this.adapter = adapter; this.state = rState; setName("BlueTooth Com"); sb = new StringBuffer(); prevBuffer = new byte[128]; readBuffer = new StringBuffer(); if (adapter == null) return; Set<BluetoothDevice> devices = adapter.getBondedDevices(); for (BluetoothDevice curDevice : devices) { if (curDevice.getName().matches(".*Lift.*")) { device = curDevice; break; } } //if (device == null) // device = adapter.getRemoteDevice("00:06:66:03:A9:A2"); //bluesmirf if (device == null) device = adapter.getRemoteDevice("00:12:6F:09:64:30"); // Rayson BTM-182 } synchronized private void connect() { int socketint = 0; while (socket == null && socketint < 10) { try { adapter.cancelDiscovery(); if (socketint == 0) { socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); }else { Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); socket = (BluetoothSocket) m.invoke(device, Integer.valueOf(socketint)); } socket.connect(); } catch (Exception e) { Log.e(TAG, "could not connect", e); socket = null; socketint++; } } if (socket == null) { return; } InputStream tmpIn = null; OutputStream tmpOut = null; try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException e) { disconnect(); return; } istream = tmpIn; ostream = tmpOut; } public boolean connected() { return this.ostream != null; } public void run() { connect(); Looper.prepare(); handler = new Handler() { @Override public void handleMessage(Message msg) { if (connected()) { if (msg.obj instanceof ControllerState) { ControllerState cs = ( (ControllerState) msg.obj ); Log.d(TAG, "Handeling Message" + msg.obj); byte[] bytes; try { bytes = cs.getTxtCommand().getBytes("ASCI"); write(bytes); } catch (UnsupportedEncodingException e) { Log.e(TAG, "could not write txt command", e); } } if (msg.obj instanceof String) { String s = (String) msg.obj; Log.d(TAG, "Handeling String" + s); byte[] bytes; try { bytes = s.getBytes("ASCI"); write(bytes); } catch (UnsupportedEncodingException e) { Log.e(TAG, "could not write txt command", e); } } read(); } else { connect(); } } }; Looper.loop(); disconnect(); } private void write(byte[] bytes) { if (ostream != null) { try { Log.d(TAG, "Writing bytes :" + bytes.length); ostream.write(bytes); prevBuffer = bytes; } catch (IOException e) { Log.e(TAG, "Error duing write", e); this.disconnect(); state.onBtDataError(); // java.io.IOException: Transport endpoint is not connected } } } private void read() { if (istream != null) { try { int inChar; while (istream.available() > 0) { inChar = istream.read(); if (inChar != 13 && inChar != 10)// do not write carriage returns or // newlines to the buffer { readBuffer.append((char) inChar); } if (inChar == 10)// look for newlines { String tmp = readBuffer.toString(); Log.i(TAG, "got bt data:" + tmp); readBuffer.delete(0, readBuffer.length()); state.onBtDataRecive(tmp); } } } catch (Exception e) { Log.e(TAG, "exception during read", e); this.disconnect(); state.onBtDataError(); } } } public void disconnect() { Log.i(TAG, "quit callled"); try { istream.close(); } catch (Exception e) { } try { ostream.close(); } catch (Exception e) { } try { socket.close(); } catch (Exception e) { // Log.e(TAG, "exception closing socket", e); } istream = null; ostream = null; socket = null; } }