// vim: et sw=4 sts=4 tabstop=4 /* * 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.issc.impl.test; import com.issc.Bluebit; import com.issc.gatt.Gatt; import com.issc.gatt.Gatt.Listener; import com.issc.gatt.GattCharacteristic; import com.issc.gatt.GattDescriptor; import com.issc.gatt.GattService; import com.issc.util.Log; import com.issc.util.Util; import java.util.ArrayList; import java.util.List; import java.util.UUID; import android.content.Context; import android.bluetooth.BluetoothDevice; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; public class FakeGattDeviceTransparent implements Gatt { private final static long DELAY = 200; // 200ms private final static String KEY_CHR_UUID = "_key_for_picking_characteristic_by_uuid_"; private final static String KEY_DSC_UUID = "_key_for_picking_descriptor_by_uuid_"; private final static int READ_CHR = 0x0010; private final static int READ_DSC = 0x0011; private final static int WRITE_CHR = 0x0012; private final static int WRITE_DSC = 0x0013; private final static int SET_CHR_NOTI = 0x0014; private FakeGattService mService; private ArrayList<GattService> mSrvs; private BluetoothDevice mDevice; private Listener mListener; private Handler mHandler; private HandlerThread mThread; public FakeGattDeviceTransparent(BluetoothDevice dev, Listener listener) { mDevice = dev; mListener = listener; mSrvs = new ArrayList<GattService>(); mThread = new HandlerThread("FakeTransparent"); mThread.start(); mHandler = new TransferHandler(mThread.getLooper()); initServices(); } private void initServices() { mService = new FakeGattService(Bluebit.SERVICE_ISSC_PROPRIETARY); FakeGattCharacteristic chr; List<UUID> uuids = new ArrayList<UUID>(); uuids.add(Bluebit.DES_CLIENT_CHR_CONFIG); chr = new FakeGattCharacteristic(mService, Bluebit.CHR_ISSC_TRANS_TX, uuids); chr.setValue(new String("ISSC").getBytes()); mService.addCharacteristic(chr); uuids.clear(); chr = new FakeGattCharacteristic(mService, Bluebit.CHR_ISSC_TRANS_RX, uuids); chr.setValue(new String("FAKE").getBytes()); mService.addCharacteristic(chr); mSrvs.add(mService); } @Override public void close() { Log.d("FakeGatt: close"); mThread.quitSafely(); mThread = null; mHandler = null; } @Override public boolean connect() { Log.d("FakeGatt: connect"); return true; } @Override public void disconnect() { Log.d("FakeGatt: disconnect"); } @Override public boolean discoverServices() { Log.d("FakeGatt: discoverServices"); return true; } @Override public BluetoothDevice getDevice() { return mDevice; } @Override public GattService getService(UUID uuid) { return mService; } @Override public List<GattService> getServices() { return mSrvs; } @Override public boolean readCharacteristic(GattCharacteristic chr) { Log.d("FakeGatt: read characteristic: " + Util.BytesToHex(chr.getValue())); Message msg = mHandler.obtainMessage(READ_CHR); Bundle data = msg.getData(); data.putSerializable(KEY_CHR_UUID, chr.getUuid()); mHandler.sendMessageDelayed(msg, DELAY); return true; } @Override public boolean readDescriptor(GattDescriptor dsc) { Log.d("FakeGatt: read descriptor: " + Util.BytesToHex(dsc.getValue())); Message msg = mHandler.obtainMessage(READ_DSC); Bundle data = msg.getData(); data.putSerializable(KEY_CHR_UUID, dsc.getCharacteristic().getUuid()); data.putSerializable(KEY_DSC_UUID, dsc.getUuid()); mHandler.sendMessageDelayed(msg, DELAY); return true; } @Override public boolean setCharacteristicNotification(GattCharacteristic chr, boolean enable) { Log.d("FakeGatt: set characteristic notification: " + enable); Message msg = mHandler.obtainMessage(SET_CHR_NOTI); Bundle data = msg.getData(); data.putSerializable(KEY_CHR_UUID, chr.getUuid()); mHandler.sendMessageDelayed(msg, DELAY); return true; } @Override public boolean writeCharacteristic(GattCharacteristic chr) { Log.d("FakeGatt: write characteristic: " + Util.BytesToHex(chr.getValue())); Message msg = mHandler.obtainMessage(WRITE_CHR); Bundle data = msg.getData(); data.putSerializable(KEY_CHR_UUID, chr.getUuid()); mHandler.sendMessageDelayed(msg, DELAY); return true; } @Override public boolean writeDescriptor(GattDescriptor dsc) { Log.d("FakeGatt: write descriptor: " + Util.BytesToHex(dsc.getValue())); Message msg = mHandler.obtainMessage(WRITE_DSC); Bundle data = msg.getData(); data.putSerializable(KEY_CHR_UUID, dsc.getCharacteristic().getUuid()); data.putSerializable(KEY_DSC_UUID, dsc.getUuid()); mHandler.sendMessageDelayed(msg, DELAY); return true; } class TransferHandler extends Handler { TransferHandler(Looper looper) { super(looper); } public void handleMessage(Message msg) { int tag = msg.what; UUID uuidChr = (UUID)msg.getData().getSerializable(KEY_CHR_UUID); UUID uuidDsc = (UUID)msg.getData().getSerializable(KEY_DSC_UUID); if (tag == READ_CHR) { GattCharacteristic chr = mService.getCharacteristic(uuidChr); mListener.onCharacteristicRead( FakeGattDeviceTransparent.this, chr, Gatt.GATT_SUCCESS); } else if (tag == READ_DSC) { GattCharacteristic chr = mService.getCharacteristic(uuidChr); GattDescriptor dsc = chr.getDescriptor(uuidDsc); mListener.onDescriptorRead( FakeGattDeviceTransparent.this, dsc, Gatt.GATT_SUCCESS); } else if (tag == WRITE_CHR) { GattCharacteristic chr = mService.getCharacteristic(uuidChr); mListener.onCharacteristicWrite( FakeGattDeviceTransparent.this, chr, Gatt.GATT_SUCCESS); } else if (tag == WRITE_DSC) { GattCharacteristic chr = mService.getCharacteristic(uuidChr); GattDescriptor dsc = chr.getDescriptor(uuidDsc); mListener.onDescriptorWrite( FakeGattDeviceTransparent.this, dsc, Gatt.GATT_SUCCESS); } else if (tag == SET_CHR_NOTI) { GattCharacteristic chr = mService.getCharacteristic(uuidChr); mListener.onCharacteristicChanged( FakeGattDeviceTransparent.this, chr); } else { Log.e("Oops, message with unknown tag"); } } } }