package com.device.comm.mylibrary.NativeDevice;

import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.util.Log;

import com.device.comm.mylibrary.BleDevice;
import com.device.comm.mylibrary.BleDeviceConnect;
import com.device.comm.mylibrary.BleDeviceManager;
import com.device.comm.mylibrary.ENDeviceConst;
import com.device.comm.mylibrary.HexUtils;
import com.device.comm.mylibrary.RNLog;
import com.device.comm.mylibrary.UpdateLoop;

import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;

/**
 * Created by lvwang2002 on 16/1/27.
 */
public class BleNativeYASEE163EBBPDevice extends BleNativeDevice {
    private String TAG ="RN_BLE_YASEE_JN163EB_BP";

    public static final String UUID_BTLE_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb";
    public static final String UUID_BTLE_SEND = "0000fff1-0000-1000-8000-00805f9b34fb";
    public static final String UUID_BTLE_RECEIVE = "0000fff4-0000-1000-8000-00805f9b34fb";
    public static final String UUID_BTLE_SETTING_CODE = "0000fca2-0000-1000-8000-00805f9b34fb";
    private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";


    BleDevice mDevice = null;
    BleDeviceManager mDeviceManager = null;
    boolean mIsReceivedState = false;
    boolean mIsAllowSendBattery = false;
    byte[] lastData = {};


    public BleNativeYASEE163EBBPDevice(BleDevice device, BleDeviceManager deviceManager){
        mDevice = device;
        mDeviceManager = deviceManager;
    }

    public enum BPStatus{
        BPStatusStartTest,
        BPStatusStopTest,BPStatusStartZero,BPStatusStopZero
    }


    @Override
    public String getNotifyCharacteristicUUID() {
        return UUID_BTLE_RECEIVE;
    }

    @Override
    public String getDeviceServiceUUID(){
        return  UUID_BTLE_SERVICE;
    }

    private synchronized boolean postNeeded() {
        return mDeviceManager.getUpdateLoop().postNeeded();
    }

    private synchronized void post(final Runnable runnable) {
        final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop();
        updateLoop.postIfNeeded(runnable);
    }

    private boolean postMainThreadNeeded() {
        return mDeviceManager.getMainUpdateLoop().postNeeded();
    }

    private synchronized void postMainThread(final Runnable runnable) {
        final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop();

        updateLoop.postIfNeeded(runnable);
    }

    BleNativeRBPDeviceCallback mDeviceCallback = null;
    @Override
    public void  setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){
        mDeviceCallback = (BleNativeRBPDeviceCallback) deviceCallback;
    }

    BluetoothGattCharacteristic mNotifyCharacteristic = null;
    BluetoothGattService mDeviceService = null;
    BluetoothGattCharacteristic mGattCharacteristicTrans = null;
    BluetoothGattCharacteristic mGattCharacteristicSettingCode = null;
    @Override
    public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) {
        if (gattStatus == BluetoothGatt.GATT_SUCCESS) {
            cleanReciveBytes();
            mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE));
            if (mDeviceService == null) {
                mDeviceManager.uhOh(mDevice, "not get device server");
                return;
            }

            mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE));
            if (mNotifyCharacteristic == null) {
                mDeviceManager.uhOh(mDevice, "not get device Characteristic");
                return;
            }

            mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND));
            if (mGattCharacteristicTrans == null) {
                mDeviceManager.uhOh(mDevice, "not get send device Characteristic");
                return;
            }
            mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);


            if (postNeeded()) {
                post(new Runnable() {
                    @Override
                    public void run() {
                        enableNotification(gatt, true, mNotifyCharacteristic);
                    }
                });
            } else {
                enableNotification(gatt, true, mNotifyCharacteristic);
            }


        } else {
            mDeviceManager.uhOh(mDevice, "service status error:" + gattStatus);
        }
        
    }

    private synchronized void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) {
        if (gatt == null){
            Log.e(TAG,"gatt 为空");
            return;
        }

        if (!(gatt.setCharacteristicNotification(characteristic, enable))){
            Log.e(TAG,"设置Gatt失败");
            mDeviceManager.uhOh(mDevice,"set gatt notify error");
            return;
        }

        BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID
                .fromString(CLIENT_CHARACTERISTIC_CONFIG));
        if (clientConfig == null){
            Log.e(TAG,"clientConfig为空,但好像也不是特别影响");
            return;
        }
        byte[] b = {
                (byte) 0x00, (byte) 0x01
        };
        try{
            clientConfig.setValue(b);
        }catch (Exception e) {
            mDeviceManager.uhOh(mDevice,"null exception");
            return;
        }

        if (enable) {
            Log.i(TAG, "enable notification");
            clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        } else {
            Log.i(TAG, "disable notification");
            clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
        }

        if(!gatt.writeDescriptor(clientConfig)){
            Log.e(TAG,"write descriptor error");

            mDeviceManager.uhOh(mDevice,"write descriptor error");
            return;
        }

    }

    /** 接收并处理数据  */
    @Override
    public synchronized void receiveData(BluetoothGattCharacteristic characteristic){
        final byte[] data = characteristic.getValue();
        RNLog.d(TAG,"received data:"+Bytes2HexString(data,0,data.length));
        onFragmentDataIn(data,data.length);

//        handlerReceivedData(data);

    }


    private static int current_size;
    private static byte[] recive_btyes;
    private static final int DATA_MAX_LENGTH = 1024;

    //把新进的数据拷贝进入累加数据
    private byte[] addBytes(byte[] oldBytes, int old_length, byte[] newBytes, int copy_length) {
        System.arraycopy(newBytes, 0, oldBytes, old_length, copy_length);
        return oldBytes;
    }

    //清空累加数据
    private void cleanReciveBytes() {
        current_size = 0;
        recive_btyes = new byte[DATA_MAX_LENGTH];
    }

    //删掉一段数据
    private byte[] delBytes(byte[] oldBytes, int indexStart, int length) {
        byte[] newBytes = new byte[DATA_MAX_LENGTH];
        int copy_index = 0;
        for (int i = 0; i < oldBytes.length; i++) {
            if (i >= indexStart && i <= length-1) {
                continue;
            }
            newBytes[copy_index] = oldBytes[i];
            copy_index++;
        }
        return newBytes;
    }

    //byte数组中包含一条完整语句，且语句前的needDeleteFrontOfResultData个数据是冗余数据
    private int needDeleteFrontOfResultData;

    //判断byte[]是否包含一条完整语句，有则返回一个ResultData对象
    private byte[] isHaveResultData(byte[] checkBytes, int checkSize) {
        needDeleteFrontOfResultData = 0;

        RNLog.d(TAG,"check is Have Result Data "+checkSize);
//        printData(checkBytes,checkSize);

        int checkIndex = 0;
        for (int a = 0; a < checkSize-1; a++) {

            if (HexUtils.getUnsignedByte(checkBytes[a]) != 0xAA && HexUtils.getUnsignedByte(checkBytes[a+1]) != 0x55) {
                //不是帧头continue
                RNLog.d(TAG,"not a start");
                continue;
            }
            //找到帧头
            checkIndex = a;
            int surplus_size = checkSize - checkIndex;//从checkIndex到checkSize剩余多少个长度

            //该条数据的长度，是否可能包含了完整的语句 1 surplus_size>=5 2 帧长<=surplus_size-1（帧头）-1（帧长）-1（校验和）
            boolean maybeCompleteData = surplus_size >= 4 && HexUtils.getUnsignedByte(checkBytes[2 + checkIndex]) <= surplus_size - 2 - 1;
            RNLog.d(TAG,"first check "+maybeCompleteData);
            if (maybeCompleteData) {
                //有可能包含一条完整语句
                int frame_length = HexUtils.getUnsignedByte(checkBytes[2 + checkIndex]);//帧长
                int funtion_id = HexUtils.getUnsignedByte(checkBytes[3 + checkIndex]);//功能字
                int device_id = HexUtils.getUnsignedByte(checkBytes[4 + checkIndex]);//设备ID
                int index_sum = 1 + frame_length + checkIndex;//校验和所在的index
                if (index_sum > checkSize) {
                    RNLog.d(TAG,"check index out");
                    return null;
                }
//                //校验和在checkSize范围内
//                int sum8low_other = checkBytes[index_sum];//校验和-对方给的 低8位
//                //校验和
                RNLog.d(TAG,"check data:"+Bytes2HexString(checkBytes,0,checkBytes.length));
                int sum = 0;
                sum += funtion_id;
                sum += device_id;
                int data_length = frame_length - 4;
                if (data_length < 0) {
                    continue;
                }
                for (int i = 0; i < data_length; i++) {
                    sum += HexUtils.getUnsignedByte(checkBytes[i + 5 + checkIndex]);
                    RNLog.d(TAG,"sum+ ="+sum);
                }

                /** 有的设备该指令 数据长度 导致验证码出现问题  */
                if(funtion_id != 0x88){
                    byte[] bytesSum = HexUtils.intToBytes2(sum);
                    int lowValue = (bytesSum[3]&0xff);
                    RNLog.d(TAG,"sum:"+sum);
                    RNLog.d(TAG,"byte sum:"+Bytes2HexString(bytesSum,0,bytesSum.length));

                    if((bytesSum[2]&0xff) != (checkBytes[checkIndex+5+data_length]&0xff) || (bytesSum[3]&0xff) != (checkBytes[checkIndex+5+data_length+1]&0xff)){
                        cleanReciveBytes();
                        return null;
                    }
                    RNLog.d(TAG,"check true");
                }


//                int sum8low_self = bytesSum[bytesSum.length - 1];//校验和-自己算的 低8位

//                if (sum8low_other != sum8low_self) {
//                    RNLog.d(TAG,"1 接收到的校验和异常 sum8low_other = " + sum8low_other + " sum8low_self = " + sum8low_self);
//                    continue;
//                } else {
                    //拿到了一条完整语句
                    //语句长度result_length = 2（帧头）+1（帧长）+1（功能字）+1(设备Id)+data_length（数据长度）+2（校验和）
                    int result_length = 2 + 1 + 1 + 1 + data_length + 2;
                    byte[] resultBytes = new byte[result_length];
                    System.arraycopy(checkBytes, checkIndex, resultBytes, 0, result_length);

//                    StringBuffer sb = new StringBuffer();
//                    sb.append("resultBytes!!!!!!!!! = ");
//                    for (int i = 0; i < resultBytes.length; i++) {
//                        sb.append(resultBytes[i]);
//                        sb.append(" ");
//                    }
//                    Lg.d(sb.toString());

//                    ResultData resultData = new ResultData(resultBytes);
                    //给needDeleteFrontOfResultData赋值，之前有冗余数据需要删除
                    needDeleteFrontOfResultData = checkIndex;

                    return resultBytes;
//                }

            }

        }
        return null;
    }


    //有数据片段进来
    private void onFragmentDataIn(byte[] newBytes, int size) {
        if(current_size<0){
            Log.d(TAG,"the value is not correct");
            cleanReciveBytes();
            return;
        }

        if((size+current_size)>DATA_MAX_LENGTH){
            Log.d(TAG,"out of max data");
            cleanReciveBytes();
            return;
        }


        //把新数据累加
        if (newBytes != null && size != 0) {
            recive_btyes = addBytes(recive_btyes, current_size, newBytes, size);
            current_size += size;
        }

        //判断累加后的数据，是否包含一条完整语句
        byte[] resultData = isHaveResultData(recive_btyes, current_size);
        //包含一条完整语句
        if (resultData != null) {
            handlerReceivedData(resultData);

            //发送回调
//            if (onDataReceiveListener != null) {
//                printReciveData(resultData);
//                onDataReceiveListener.onSerialResultData(resultData);
//            }
            if (needDeleteFrontOfResultData > 0) {
//                Lg.d("删除冗余"+needDeleteFrontOfResultData+"个");

//                StringBuffer sb = new StringBuffer("删除冗余"+needDeleteFrontOfResultData+"个，删除内容:");
//                for (int i=0;i<needDeleteFrontOfResultData;i++){
//                    sb.append(" "+HexUtils.bytesToHexString(recive_btyes[i]));
//                }
//                Lg.d(sb.toString());

                //需要删除冗余数据，则删除
                recive_btyes = delBytes(recive_btyes, 0, needDeleteFrontOfResultData);
                current_size -= needDeleteFrontOfResultData;

//                sb = new StringBuffer();
//                sb.append("下一条语句：");
//                for (int i=0;i<resultData.getAll_length();i++){
//                    sb.append(" "+HexUtils.bytesToHexString(recive_btyes[i]));
//                }
//                Lg.d(sb.toString());

            }

            //把这条完整的语句从累加数据中删除
            recive_btyes = delBytes(recive_btyes, 0,resultData.length);
            current_size -= resultData.length;

            //删除后再次判断，后面是否含有完整语句
            onFragmentDataIn(null, 0);
        }
        //不包含一条完整语句
        else {
            RNLog.d(TAG,"not a command");
        }
    }

    private synchronized void sendData(byte[] data) {
        if(mDevice.getDeviceConnect().getGatt() == null){
            return;
        }

        if (data != null && data.length > 0 && data.length < 21) {
            if (mGattCharacteristicTrans.setValue(data)
                    && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) {
                Log.i(TAG, "send data OK");
            }else{
                Log.i(TAG,"发送失败");
            }
        }else{
            Log.i(TAG,"数据长度不在指定范围内");
        }
    }

    private int BLEPacketSize = 20;
    public synchronized void sendBigData(byte[] data){
        int length = data.length/BLEPacketSize+(data.length%BLEPacketSize>0?1:0);
        RNLog.d(TAG,"data length:"+data.length);
        RNLog.d(TAG,"big data length:"+length);
        for(int i=0;i<length;i++){
            int dataLength = ((i*BLEPacketSize+BLEPacketSize)<data.length)?BLEPacketSize:(data.length-i*BLEPacketSize);
            RNLog.d(TAG,"data length:"+dataLength);
            byte[] sendData = ByteUtil.getByteArr(data,i*BLEPacketSize,i*BLEPacketSize+dataLength);
            RNLog.d(TAG,"send data:"+ Bytes2HexString(sendData,0,sendData.length));
            sendData(sendData);


            try{
                Thread.sleep(100);
            }catch (InterruptedException error){
                RNLog.d(TAG,"error:"+error);
                error.printStackTrace();
            }
        }
    }

    /* 发送设置码 */
    private synchronized void sendSettingCode() {
        if(mDevice == null){
            mDeviceManager.uhOh(mDevice,"error");
            return;
        }

        byte[] data = {(byte) 0xf0, (byte) 0xD2, (byte) 0xA9, (byte) 0xC6, (byte) 0x0F, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
        Log.i(TAG,""+data.length);
        if (data != null && data.length > 0 && data.length < 21) {
            if (mGattCharacteristicSettingCode.setValue(data)
                    && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicSettingCode)) {
                Log.i(TAG, "send data OK");
            }else{
                Log.i(TAG,"数据长度不在指定范围内");
            }
        }
    }

    /** 发送连接状态 */
    private synchronized void sendStatusConnected(){
        byte[] data ={(byte)0x04,(byte)0xa1,(byte)0xa0,(byte)0x45};
        sendData(data);
    }

    /** 开始测量 */
    public synchronized void sendStartTest(){
//        0xAA,0x55,0x0A,0x85,0x02,0x15, 0x06,0x1E,0x10,0x10,0x10,0x00,0xF0
        byte[] list = getTimeInfo();
        byte[] data =  {(byte)0x85,(byte)0x02,list[0],list[1],list[2],list[3],list[4],list[5]};
        int verifyValue = countVerify(data);

        byte[] sendCmd = {(byte)0xaa,(byte)0x55,(byte)0x0a,data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],(byte)(verifyValue>>8),(byte)(verifyValue%256)};
        sendData(sendCmd);
    }

    /** 停止测量 */
    public  synchronized void sendStopTest(){
        Log.i(TAG,"发送停止测量");
//        0xAA,0x55,0x0A,0x86,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88
        byte[] list = getTimeInfo();
        byte[] data =  {(byte)0x86,(byte)0x02,list[0],list[1],list[2],list[3],list[4],list[5]};
        int verifyValue = countVerify(data);

        byte[] sendCmd = {(byte)0xaa,(byte)0x55,(byte)0x0a,data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],(byte)(verifyValue>>8),(byte)(verifyValue%256)};
        sendData(sendCmd);
    }

    /** 获取电量 */
    public  synchronized void sendGetBatteryValue(){
        Log.i(TAG,"获取电量");
        byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa5,(byte)0x4a};
        sendData(data);
    }

    /** 获取设备id */
    public synchronized void sendGetDeviceID(){
        Log.i(TAG,"获取DeviceID");
        byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa4,(byte)0x49};
        sendData(data);
    }

    /** 血压计关机 */
    public synchronized void sendPowerOffDevice(){
        Log.i(TAG,"要求设备关机");
        byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa6,(byte)0x4b};
        sendData(data);
    }

    /** 设置血压ID */
    public synchronized  void sendSetDeviceID(){
        Log.i(TAG,"设置DeviceID");
        byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa3,(byte)0x01,(byte)0xff,(byte)0xaa,(byte)0xf5};
        sendData(data);
    }

    /** 查询咨询密码 */
    public synchronized void searchSettingCode(){
        Log.i(TAG,"查询配置码");
        byte[] data = {(byte)0x04,(byte)0x55,(byte)0xaa,(byte)0x03};
        sendData(data);
    }

    /** 设置血压计日期 */
    public synchronized void sendSetDeviceDate(){
        Log.i(TAG,"设置日期");
        byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa8,(byte)0x0e,(byte)0x0a,(byte)0x08,(byte)0x70};
        sendData(data);
    }

    /** 设置血压时间 */
    public synchronized void sendSetDeviceTime(){
        Log.i(TAG,"设置时间");
        byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa9,(byte)0x17,(byte)0x2d,(byte)0x08,(byte)0x9d};
        sendData(data);
    }

    /** 读取血糖历史  */
    public synchronized void sendGetHistory(){
        Log.i(TAG,"获取历史数据");

        byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xac,(byte)0x51};
        sendData(data);
    }

    /** 断开蓝牙  */
    public synchronized void sendTurnOffBT(){
        Log.i(TAG,"断开蓝牙");
        byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xad,(byte)0x52};
        sendData(data);
    }

    /** 设置自动测量血压数据 */
    public synchronized void sendSetDyBP(){
        Log.i(TAG,"设置血压");
        byte[] data = {
                (byte)0x15,(byte)0xa1,(byte)0xc0,
                (byte)0x11,(byte)0x09,(byte)0x0c,(byte)0x08,(byte)0x13,(byte)0x00,
                (byte)0x07,(byte)0x1e,(byte)0x15,(byte)0x1e,(byte)0x05,
                (byte)0x15,(byte)0x1e,(byte)0x07,(byte)0x1e,(byte)0x05,
                (byte)0x11,
//                (byte)0xd2
        };
        byte verify = (byte)countVerify(data);
        RNLog.d(TAG,""+countVerify(ByteUtil.getByteArr(data,0,20)));
        byte[] verifyList = {verify};
        data = concat(data,verifyList);

        sendBigData(data);
    }

    private int countVerify(byte[] dataList){
        int verifyData = 0;
        for(byte data:dataList){
            verifyData = verifyData + (data&0xff);
        }
        return verifyData;

    }

    private byte[] getTimeInfo(){
        final Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));

        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH)+1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);

        byte[] list = {(byte)(year%100),(byte)month,(byte)day,(byte)hour,(byte)minute,(byte)second};
        return list;

    }
    public static byte[] concat(byte[] first, byte[] second) {
        byte[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }


    public synchronized void postDelay(Runnable runnable,long delayMillis){
        final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop();
        updateLoop.postDelay(runnable,delayMillis);
    }


    private synchronized void respondBP(){
        Log.i(TAG,"回应动态血压的值");
        byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xc8,(byte)0x6d};
        sendData(data);
    }

    /** 对接收的数据进行处理 */
    private synchronized void handlerReceivedData(byte[] data){
//        if(data.length<4){
//            return;
//        }
//
//        if(isArrayEqual(data,lastData)){
//            return;
//        }
//
//        lastData = data;
//
//        if((data[0]&0xff)!=0xff && (data[1]&0xff)!=0xfe){
//            return;
//        }
//
//        if(data[2] != data.length-2){
//            Log.i(TAG,"指令长度不符");
//            return;
//        }
        RNLog.d(TAG,"start hand received data");
        int commandFlag = (data[3] & 0xff);
        switch (commandFlag){


            case 0xa0:{
                Log.i(TAG,"接收到连接状态");
            }
            break;

            case 0x50:{
                //血压计通知开始测量
                Log.i(TAG,"start test");
                if(mDeviceCallback != null){
                    postMainThread(new Runnable() {
                        @Override
                        public void run() {
                            if(mDeviceCallback==null){
                                return;
                            }
                            mDeviceCallback.onStartTest(mDevice);
                        }
                    });
                }
            }
            break;
            case 0x53:{
                //血压计通知测量停止测量
                Log.i(TAG,"stop test");
                if(mDeviceCallback != null){
                    postMainThread(new Runnable() {
                        @Override
                        public void run() {
                            if(mDeviceCallback==null){
                                return;
                            }
                            mDeviceCallback.onStopTest(mDevice);
                        }
                    });
                }
            }
            break;
            case 0xb3:{
                //血压计通知正在归零
                Log.i(TAG,"stop test start zero");
            }
            break;
            case 0xb4:{
                //血压计通知归零结束
                Log.i(TAG,"stop test stop zero");
                //血压计通知开始测量
                Log.i(TAG,"start test");
                if(mDeviceCallback != null){
                    postMainThread(new Runnable() {
                        @Override
                        public void run() {
                            mDeviceCallback.onStopZero(mDevice);
                        }
                    });
                }
            }
            break;


            case 0x87:{
                //血压计发送过程数据
                boolean isHeart = ((data[7]&0xff) == 0x01);
                int value = (((data[6]&0xff) & 0x0f) & 0xff)*256 + (data[5] & 0xff);
                RNLog.d(TAG,"blood value:"+value+"  is heart:"+isHeart);

                if(mDeviceCallback != null){
                    final Map<String,String> info = new HashMap<String, String>();
                    info.put("value",""+value);
                    info.put("isHeart",""+isHeart);
                    postMainThread(new Runnable() {
                        @Override
                        public void run() {
                            mDeviceCallback.onProgressValue(mDevice,info);
                        }
                    });
                }

            }
            break;

            case 0x88:{
                //血压计发送测量结果
                if((data[5]&0xff)>0 && (data[5]&0xff)<=7 && data[6] == 0 && data[7] == 0 && data[8] == 0 && data[9] == 0){
                    //进入错误处理
                    String[] errorTypes = {
                            "漏气速度太快或脉搏信号弱",
                            "杂讯太多无法测得电压信号",
                            "测量结果不准确",
                            "用户终止",
                            "充气失败",
                            "充气压力大于300mmhg",
                            "电压不足 3.6V±0.2"
                    };



                    if(mDeviceCallback != null){
                        final Map<String,String> info = new HashMap<String, String>();
                        info.put("errorCode",""+""+""+data[5]);
                        info.put("error",""+""+""+errorTypes[data[5]-1]);

                        postMainThread(new Runnable() {
                            @Override
                            public void run() {
                                mDeviceCallback.onError(mDevice,info);
                            }
                        });
                        return;
                    }
                }



                int sysValue = (((data[6]&0xff) & 0x0f)&0xff)*256 + (data[5]&0xff);
                int diaValue =  (data[7]&0xff);
                int pulValue = data[8] & 0xff;
                boolean isHeart = ((data[9]&0xff) == 0x01);

                Log.i(TAG,"dia value:"+diaValue+" sys value:"+sysValue);
                Log.i(TAG,"pul:"+pulValue+"is heart:"+isHeart);

                if(mDeviceCallback != null){
                    final Map<String,String> info = new HashMap<String, String>();
                    info.put("dia",""+diaValue);
                    info.put("sys",""+sysValue);
                    info.put("pul",""+pulValue);
                    info.put("isHeart",""+isHeart);
                    postMainThread(new Runnable() {
                        @Override
                        public void run() {
                            mDeviceCallback.onResult(mDevice,info);
                        }
                    });

                }

            }
            break;
            case 0x56:{
                //血压计发送测量错误信息
                Log.i(TAG,"error:"+data[5]);
                String[] errorTypes = {
                        "气袋没绑好",
                        "进入超压保护",
                        "测量不到有效脉搏",
                        "测量中干预过多",
                        "测量结果数值有误",
                        "电池地电话",
                        "EEPROM有误"
                        };



                if(mDeviceCallback != null){
                    final Map<String,String> info = new HashMap<String, String>();
                    info.put("errorCode",""+""+""+data[5]);
                    info.put("error",""+""+""+errorTypes[data[5]-1]);

                    postMainThread(new Runnable() {
                        @Override
                        public void run() {
                            mDeviceCallback.onError(mDevice,info);
                        }
                    });
                }

            }
            break;

            case 0xba:{
                //血压计发送关机信号
                Log.i(TAG,"血压计发送关机信号");
                if(mDeviceCallback != null){
                    postMainThread(new Runnable() {
                        @Override
                        public void run() {
                            mDeviceCallback.onDeviceShutDown(mDevice);;
                        }
                    });
                }
            }
            break;

            case 0xbb:{
                //血压计发送低电信号
                Log.i(TAG,"血压计发送低电信号");
                if(mDeviceCallback != null){
                    final Map<String,String> info = new HashMap<String, String>();
                    info.put("errorCode",""+""+""+101);
                    info.put("error",""+""+""+"电量不足，请更换电池");

                    postMainThread(new Runnable() {
                        @Override
                        public void run() {
                            mDeviceCallback.onError(mDevice,info);
                        }
                    });
                }
            }
            break;

            case 0xbc:{
                //接收时间设置
                Log.i(TAG,"血压计时间设置成功");
            }
            break;
        }
    }

    private boolean isArrayEqual(byte[] a,byte[] b) {
        if (a.length != b.length) {
            return false;
        }

        for (int i = 0; i < a.length; i++) {
            if (a[i] != b[i]) {
                return false;
            }
        }
        return true;
    }

    @Override
    public String getDeviceDisplayName(){
        return "雅思电子血压计";
    }

    @Override
    public boolean disableNotifications() {
        BleDeviceConnect connect  = mDevice.getDeviceConnect();
        if(connect == null){
            return false;
        }

        BluetoothGatt gatt = connect.getGatt();
        if (gatt == null || mNotifyCharacteristic == null)
            return false;

        if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false)))
            return false;

        BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG));
        if (clientConfig == null)
            return false;

        Log.i(TAG, "disable notification");
        clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);

        return gatt.writeDescriptor(clientConfig);
    }

    @Override
    public String getDeviceType(){
        return ENDeviceConst.DEVICE_TYPE_YASEE_JN163_BP;
    }

}
