public class BluetoothPort implements IPrinterPort {
private static final String TAG = "BluetoothPort";
private BluetoothDevice mDevice;
private static String mDeviceName;
private static String mDeviceAddress;
private static BluetoothSocket mSocket;
private BluetoothAdapter mAdapter;
private BluetoothPort.ConnectThread mConnectThread;
private static InputStream inputStream;
private static OutputStream outputStream;
private Context mContext;
private Handler mHandler;
private int mState;
private static int readLen;

private final UUID PRINTER_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

private PrinterInstance mPrinter;
private BroadcastReceiver boundDeviceReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if("android.bluetooth.device.action.BOND_STATE_CHANGED".equals(action)) {
            BluetoothDevice device = (BluetoothDevice)intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
            if(!BluetoothPort.this.mDevice.equals(device)) {
                return;
            }

            switch(device.getBondState()) {
                case 10:
                    BluetoothPort.this.mContext.unregisterReceiver(BluetoothPort.this.boundDeviceReceiver);
                    BluetoothPort.this.setState(102);
                    Utils.Log("BluetoothPort", "bound cancel");
                    break;
                case 11:
                    Utils.Log("BluetoothPort", "bounding......");
                    break;
                case 12:
                    Utils.Log("BluetoothPort", "bound success");
                    BluetoothPort.this.mContext.unregisterReceiver(BluetoothPort.this.boundDeviceReceiver);
                    BluetoothPort.this.PairOrConnect(false);
            }
        }

    }
};

public BluetoothPort(Context context, BluetoothDevice device, Handler handler) {
    this.mHandler = handler;
    this.mDevice = device;
    this.mAdapter = BluetoothAdapter.getDefaultAdapter();
    this.mState = 103;
    this.mContext = context;
}

public BluetoothPort() {
}

public BluetoothPort(Context context, String address, Handler handler) {
    this.mHandler = handler;
    this.mAdapter = BluetoothAdapter.getDefaultAdapter();
    this.mDevice = this.mAdapter.getRemoteDevice(address);
    this.mState = 103;
    this.mContext = context;
}

public void open() {
    Utils.Log("BluetoothPort", "connect to: " + this.mDevice.getName());
    if(this.mState != 103) {

        this.close();

    }

    if(this.mDevice.getBondState() == 10) {
        Log.i("BluetoothPort", "device.getBondState() is BluetoothDevice.BOND_NONE");
        this.PairOrConnect(true);
    } else if(this.mDevice.getBondState() == 12) {
        this.PairOrConnect(false);
    }

}

private void PairOrConnect(boolean pair) {
    if(pair) {
        IntentFilter boundFilter = new IntentFilter("android.bluetooth.device.action.BOND_STATE_CHANGED");
        this.mContext.registerReceiver(this.boundDeviceReceiver, boundFilter);
        boolean success = false;

        try {
            Method createBondMethod = BluetoothDevice.class.getMethod("createBond", new Class[0]);
            success = ((Boolean)createBondMethod.invoke(this.mDevice, new Object[0])).booleanValue();
        } catch (IllegalAccessException var5) {
            var5.printStackTrace();
        } catch (IllegalArgumentException var6) {
            var6.printStackTrace();
        } catch (InvocationTargetException var7) {
            var7.printStackTrace();
        } catch (NoSuchMethodException var8) {
            var8.printStackTrace();
        }

        Log.i("BluetoothPort", "createBond is success? : " + success);
    } else {
        //this.mConnectThread = new BluetoothPort.ConnectThread((BluetoothPort.ConnectThread)null);
        //this.mConnectThread.start();
    }

}

@TargetApi(10)
private boolean ReTryConnect() {
    Utils.Log("BluetoothPort", "android SDK version is:" + Build.VERSION.SDK_INT);

    try {
        if(Build.VERSION.SDK_INT >= 10) {
            mSocket = this.mDevice.createInsecureRfcommSocketToServiceRecord(this.PRINTER_UUID);
        } else {
            Method method = this.mDevice.getClass().getMethod("createRfcommSocket", new Class[]{Integer.TYPE});
            mSocket = (BluetoothSocket)method.invoke(this.mDevice, new Object[]{Integer.valueOf(1)});
        }

        mSocket.connect();
        return false;
    } catch (Exception var2) {
        Log.e(TAG, "فشل1") ;
        Utils.Log("BluetoothPort", "connect failed:");
        var2.printStackTrace();
        return true;
    }
}

public void close() {

    Utils.Log("BluetoothPort", "close()");

    try {

        if(mSocket != null) {
            Log.e(TAG, "فشل2") ;
            mSocket.close();

        }
    } catch (IOException var2) {
        Log.e(TAG, "فشل2") ;
        Utils.Log("BluetoothPort", "close socket failed");
        var2.printStackTrace();
    }

    this.mConnectThread = null;
    this.mDevice = null;
    mSocket = null;
    if(this.mState != 102) {
        this.setState(103);
    }

}

public int write(byte[] data) {
    try {
        if(outputStream != null) {
            outputStream.write(data);
            outputStream.flush();
            return 0;
        } else {
            return -1;
        }
    } catch (IOException var3) {
        Log.e(TAG, "فشل3") ;
        Utils.Log("BluetoothPort", "write error.");
        var3.printStackTrace();
        return -1;
    }
}

public byte[] read() {
    byte[] readBuff = null;

    try {
        if(inputStream != null && (readLen = inputStream.available()) > 0) {
            readBuff = new byte[readLen];
            inputStream.read(readBuff);
        }
    } catch (IOException var3) {
        Log.e(TAG, "فشل4") ;
        Utils.Log("BluetoothPort", "read error");
        var3.printStackTrace();
    }

    Log.w("BluetoothPort", "read length:" + readLen);
    return readBuff;
}

public static synchronized byte[] read(int timeout) {
    byte[] receiveBytes = null;

    try {
        while((readLen = inputStream.available()) <= 0) {
            timeout -= 50;
            if(timeout <= 0) {
                break;
            }

            try {
                Thread.sleep(50L);
            } catch (InterruptedException var3) {
                Log.e(TAG, "فشل5") ;
                var3.printStackTrace();
            }
        }

        if(readLen > 0) {
            receiveBytes = new byte[readLen];
            inputStream.read(receiveBytes);
        }
    } catch (IOException var4) {
        Log.e(TAG, "فشل6") ;
        Utils.Log("BluetoothPort", "read error1");
        var4.printStackTrace();
    }

    return receiveBytes;
}

private synchronized void setState(int state) {
    Utils.Log("BluetoothPort", "setState() " + this.mState + " -> " + state);
    if(this.mState != state) {
        this.mState = state;
        if(this.mHandler != null) {
            this.mHandler.obtainMessage(this.mState).sendToTarget();
        }
    }

}

public int getState() {
    return this.mState;
}

public PrinterInstance btAutoConn(Context context, BluetoothAdapter adapter, Handler mHandler) {
    Properties pro = Utils.getBtConnInfo(context);
    mDeviceAddress = pro.getProperty("mac");
    if(mDeviceAddress != null && !mDeviceAddress.equals("")) {
        Log.v("mac", mDeviceAddress);
        this.mDevice = adapter.getRemoteDevice(mDeviceAddress);
        mDeviceName = this.mDevice.getName();
        this.mPrinter = new PrinterInstance(context, this.mDevice, mHandler);
        this.mPrinter.openConnection();
        Log.v("btport", "open-success!");
        return this.mPrinter;
    } else {
        return null;
    }
}

public PrinterInstance btConnnect(Context context, String mac, BluetoothAdapter adapter, Handler mHandler) {
    this.mDevice = adapter.getRemoteDevice(mac);
    this.mPrinter = new PrinterInstance(context, this.mDevice, mHandler);
    this.mPrinter.openConnection();
    Log.v("btport", "open-success!");
    return this.mPrinter;
}

public static byte getData(int time) {
    byte data = 0;

    try {
        InputStream inputStream = mSocket.getInputStream();

        for(int j = 0; j < 5; ++j) {
            if(inputStream.available() != 0) {
                byte[] b = new byte[inputStream.available()];
                int i = inputStream.read(b);
                if(j != 0) {
                    data = b[i - 1];
                    break;
                }
            }

            Thread.sleep((long)time);
            write1(new byte[]{16, 4, 2});
        }
    } catch (Exception var6) {
        Log.e(TAG, "فشل8") ;
        Log.e("TAG", var6.toString());
    }

    return data;
}

public static byte getEndData(int time) {
    byte ret = 0;

    try {
        InputStream inputStream = mSocket.getInputStream();

        for(int j = 0; j < 5; ++j) {
            if(inputStream.available() != 0) {
                byte[] b = new byte[inputStream.available()];
                int i = inputStream.read(b);
                if(j != 0) {
                    ret = b[i - 1];
                    break;
                }
            }

            Thread.sleep((long)time);
            write1(new byte[]{27, 118});
        }
    } catch (Exception var6) {
        Log.e(TAG, "فشل9") ;
        var6.printStackTrace();
    }

    return ret;
}

public static int write1(byte[] data) {
    try {
        if(outputStream != null) {
            Log.e(TAG, "فشل2") ;
            outputStream.write(data);
            outputStream.flush();
            return 0;
        } else {
            return -1;
        }
    } catch (IOException var2) {
        Log.e(TAG, "فشل10") ;
        Utils.Log("BluetoothPort", "write error.");
        var2.printStackTrace();
        return -1;
    }
}

public static String getmDeviceName() {
    return mDeviceName;
}

public static void setmDeviceName(String mDeviceName) {
    mDeviceName = mDeviceName;
}

public static String getmDeviceAddress() {
    return mDeviceAddress;
}

public static void setmDeviceAddress(String mDeviceAddress) {
    mDeviceAddress = mDeviceAddress;
}

private class ConnectThread extends Thread {
    private ConnectThread() {
    }



    public void run() {
        mAdapter.cancelDiscovery();
        try {
            Log.e(TAG, "فشل2") ;
            Thread.sleep(1000L);
        } catch (InterruptedException var6) {
            Log.e(TAG, "فشل11") ;
            var6.printStackTrace();
        }

        boolean hasError = false;
        BluetoothPort.this.mAdapter.cancelDiscovery();

        try {
            BluetoothPort.mSocket = BluetoothPort.this.mDevice.createRfcommSocketToServiceRecord(BluetoothPort.this.PRINTER_UUID);
            BluetoothPort.mSocket.connect();
        } catch (IOException var5) {
            Log.e(TAG, "فشل12") ;
            Utils.Log("BluetoothPort", "ConnectThread failed. retry.");
            var5.printStackTrace();
            hasError = BluetoothPort.this.ReTryConnect();
        }

        synchronized(this) {
            BluetoothPort.this.mConnectThread = null;
        }

        if(!hasError) {
            try {
                BluetoothPort.inputStream = BluetoothPort.mSocket.getInputStream();
                BluetoothPort.outputStream = BluetoothPort.mSocket.getOutputStream();
            } catch (IOException var3) {
                Log.e(TAG, "فشل13") ;
                hasError = true;
                Utils.Log("BluetoothPort", "Get Stream failed");
                var3.printStackTrace();
            }
        }

        if(hasError) {
            BluetoothPort.this.setState(102);
            BluetoothPort.this.close();
        } else {
            BluetoothPort.this.setState(101);
        }

    }
    public void cancel() {
        try {
            mSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "Could not close the client socket", e);
        }
    }
}