解析从蓝牙HDP设备接收的原始数据

时间:2013-03-23 20:21:32

标签: java android bluetooth

我正在尝试从连续健康联盟认证的欧姆龙708-BT血压监测仪中读取数据。我正在关注此示例of a Bluetooth HDP App。我正在设法连接到设备并以字节格式检索数据,但无法解析数据以获取所需的值。我正在尝试遵循此PDF第19页中指定的IEEE血压规范。

以下是已添加到上面链接的示例代码中的代码。

//Variables in the class
private int count;
private byte[] invoke = {0x00, 0x00};
private class ReadThread extends Thread {
    private ParcelFileDescriptor mFd;

    public ReadThread(ParcelFileDescriptor fd) {
        super();
        mFd = fd;
    }

    @Override
    public void run() {
        FileInputStream fis = new FileInputStream(mFd.getFileDescriptor());
        final byte data[] = new byte[300];
        try {
            while(fis.read(data) > -1) {
                // At this point, the application can pass the raw data to a parser that
                // has implemented the IEEE 11073-xxxxx specifications.  Instead, this sample
                // simply indicates that some data has been received
                Log.e("Test", data.toString()); 

                 if (data[0] != (byte) 0x00)
                 {
                     String test = byte2hex(data);
                     Log.i(TAG, test);
                     if(data[0] == (byte) 0xE2){
                         Log.i(TAG, "E2");
                         count = 1;

                         (new WriteThread(mFd)).start();
                         try {
                             sleep(100);
                         } catch (InterruptedException e) {
                             e.printStackTrace();
                         }
                         Log.i(TAG, "Seconds Write Thread");
                         count = 2;
                         (new WriteThread(mFd)).start();
                     }
                     else if (data[0] == (byte)0xE7){
                         Log.i(TAG, "E7");

                         count = 3; 
                         //set invoke id so get correct response
                         invoke = new byte[] { data[6], data[7] };
                         (new WriteThread(mFd)).start();     
                         //parse data!!
                         int number_of_data_packets = data[25];
                         int packet_start = 30;
                         final int SYS_DIA_MAP_DATA = 1;
                         final int PULSE_DATA = 2;
                         final int ERROR_CODE_DATA = 3;

                         for (int i = 0; i < number_of_data_packets; i++){
                                Log.e("TEST", Integer.toString(i));
                               int obj_handle = data[packet_start+1];
                               switch (obj_handle)
                               {
                               case SYS_DIA_MAP_DATA:
                                   int sys = byteToUnsignedInt(data[packet_start+9]);
                                   int dia = byteToUnsignedInt(data[packet_start+11]);
                                   int map = byteToUnsignedInt(data[packet_start+13]);
                                   //create team string... 9+13~9+20   
                                   Log.e("RESULT", "sys is "+ sys);
                                   sendMessage(RECEIVED_SYS, sys);
                                   Log.e("RESULT", "dia is "+ dia);
                                   sendMessage(RECEIVED_DIA, dia);
                                   Log.e("RESULT", "map is "+ map);

                                   break;
                               case PULSE_DATA:
                                   //parse
                                   int pulse = byteToUnsignedInt(data[packet_start+5]);
                                   Log.e("RESULT", "pulse is " + pulse);
                                   sendMessage(RECEIVED_PUL, pulse);
                                   break;
                               case ERROR_CODE_DATA:
                                   //need more signal
                                   break;
                               }
                               packet_start += 1;//4 + data[packet_start+3];   //4 = ignore beginning four bytes
                           }  
                     }
                     else if (data[0] == (byte) 0xE4)
                     {

                         count = 4;
                         (new WriteThread(mFd)).start();
                     }
                     //zero out the data
                     for (int i = 0; i < data.length; i++){
                         data[i] = (byte) 0x00;
                     }
                 }
                 sendMessage(STATUS_READ_DATA, 0);
            }
        } catch(IOException ioe) {}
        if (mFd != null) {
            try {
                mFd.close();
            } catch (IOException e) { /* Do nothing. */ }
        }
        sendMessage(STATUS_READ_DATA_DONE, 0);
    }
}

private class WriteThread extends Thread {
    private ParcelFileDescriptor mFd;

    public WriteThread(ParcelFileDescriptor fd) {
        super();
        mFd = fd;
    }

    @Override
    public void run() {
        FileOutputStream fos = new FileOutputStream(mFd.getFileDescriptor());
        final byte data_AR[] = new byte[] {         (byte) 0xE3, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x2C, 
                                                    (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x50, (byte) 0x79,
                                                    (byte) 0x00, (byte) 0x26,
                                                    (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x80, (byte) 0x00,
                                                    (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x08,  //bt add for phone, can be automate in the future
                                                    (byte) 0x3C, (byte) 0x5A, (byte) 0x37, (byte) 0xFF, 
                                                    (byte) 0xFE, (byte) 0x95, (byte) 0xEE, (byte) 0xE3,
                                                    (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x00, 
                                                    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
        final byte data_DR[] = new byte[] {         (byte) 0xE7, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x12,
                                                    (byte) 0x00, (byte) 0x10,
                                                    (byte) invoke[0], (byte) invoke[1],
                                                    (byte) 0x02, (byte) 0x01,
                                                    (byte) 0x00, (byte) 0x0A,
                                                    (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x0D, (byte) 0x1D,
                                                    (byte) 0x00, (byte) 0x00 };

        final byte get_MDS[] = new byte[] {         (byte) 0xE7, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x0E,
                                                    (byte) 0x00, (byte) 0x0C,
                                                    (byte) 0x00, (byte) 0x24,
                                                    (byte) 0x01, (byte) 0x03,
                                                    (byte) 0x00, (byte) 0x06,
                                                    (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x00 };

        final byte data_RR[] = new byte[] {         (byte) 0xE5, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x02,
                                                    (byte) 0x00, (byte) 0x00 };

        final byte data_RRQ[] = new byte[] {        (byte) 0xE4, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x02,
                                                    (byte) 0x00, (byte) 0x00 };

        final byte data_ABORT[] = new byte[] {      (byte) 0xE6, (byte) 0x00,
                                                    (byte) 0x00, (byte) 0x02,
                                                    (byte) 0x00, (byte) 0x00 };
        try {
            Log.i(TAG, String.valueOf(count));
            if (count == 1)
            {
                fos.write(data_AR);
                Log.i(TAG, "Association Responded!");
            }  
            else if (count == 2)
            {
                fos.write(get_MDS);
                Log.i(TAG, "Get MDS object attributes!");
            }
            else if (count == 3) 
            {
                fos.write(data_DR);
                Log.i(TAG, "Data Responsed!");
            }
            else if (count == 4)
            {
                fos.write(data_RR);
                Log.i(TAG, "Data Released!");
            }
        } catch(IOException ioe) {}
    }

数据的十六进制表示如下。我相信这些数据可以保持血压值的值,但可能是错误的。我认为这是唯一的原因是因为在上面链接的PDF中,数据将以十六进制值e7开始。

  

03-23 20:14:44.186:I / BluetoothHDPService(23652):   e70000da00d80024020300d20000000a00cc0928002000104f4d524f4e204845414c544843415245000c48454d2d373038312d4954000984000a0008002209225835c3280a5a000800010004100700010a4400024000092d00360002003200010001001653455249414c5f4e554d4245523a200000000000004100050001001046575f5245564953494f4e3a203130310914000400005dc00a4b0016000200120201000801000001000200070202000200000a450010c0101f00ffffffff00640000000000000a550008000100040a620006098700082010010100013600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

任何帮助都会非常感激。提前致谢。

6 个答案:

答案 0 :(得分:9)

我设法解决了这个问题。我遇到的主要问题是我只接受了一次血压读数,然后继续按下上传。这会上传一些有关显示器的信息,但不包括血压读数。一旦我知道了这一点,我就有其他一些较小的错误要解决,但没有太复杂。最终工作服务的代码如下。

public class BluetoothHDPService extends Service {
    private static final String TAG = "BluetoothHDPService";

    public static final int RESULT_OK = 0;
    public static final int RESULT_FAIL = -1;

    // Status codes sent back to the UI client.
    // Application registration complete.
    public static final int STATUS_HEALTH_APP_REG = 100;
    // Application unregistration complete.
    public static final int STATUS_HEALTH_APP_UNREG = 101;
    // Channel creation complete.
    public static final int STATUS_CREATE_CHANNEL = 102;
    // Channel destroy complete.
    public static final int STATUS_DESTROY_CHANNEL = 103;
    // Reading data from Bluetooth HDP device.
    public static final int STATUS_READ_DATA = 104;
    // Done with reading data.
    public static final int STATUS_READ_DATA_DONE = 105;

    // Message codes received from the UI client.
    // Register client with this service.
    public static final int MSG_REG_CLIENT = 200;
    // Unregister client from this service.
    public static final int MSG_UNREG_CLIENT = 201;
    // Register health application.
    public static final int MSG_REG_HEALTH_APP = 300;
    // Unregister health application.
    public static final int MSG_UNREG_HEALTH_APP = 301;
    // Connect channel.
    public static final int MSG_CONNECT_CHANNEL = 400;
    // Disconnect channel.
    public static final int MSG_DISCONNECT_CHANNEL = 401;

    public static final int RECEIVED_SYS = 901;

    public static final int RECEIVED_DIA = 902;

    public static final int RECEIVED_PUL = 903;

    private int count;
    private byte[] invoke = {0x00, 0x00};

    private BluetoothHealthAppConfiguration mHealthAppConfig;
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothHealth mBluetoothHealth;
    private BluetoothDevice mDevice;
    private int mChannelId;

    private Messenger mClient;

    // Handles events sent by {@link HealthHDPActivity}.
    @SuppressLint("HandlerLeak")
    private class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                // Register UI client to this service so the client can receive messages.
                case MSG_REG_CLIENT:
                    Log.d(TAG, "Activity client registered");
                    mClient = msg.replyTo;
                    break;
                // Unregister UI client from this service.
                case MSG_UNREG_CLIENT:
                    mClient = null;
                    break;
                // Register health application.
                case MSG_REG_HEALTH_APP:
                    registerApp(msg.arg1);
                    break;
                // Unregister health application.
                case MSG_UNREG_HEALTH_APP:
                    unregisterApp();
                    break;
                // Connect channel.
                case MSG_CONNECT_CHANNEL:
                    mDevice = (BluetoothDevice) msg.obj;
                    connectChannel();
                    break;
                // Disconnect channel.
                case MSG_DISCONNECT_CHANNEL:
                    mDevice = (BluetoothDevice) msg.obj;
                    disconnectChannel();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * Make sure Bluetooth and health profile are available on the Android device.  Stop service
     * if they are not available.
     */
    @SuppressLint("ShowToast")
    @Override
    public void onCreate() {
        super.onCreate();

        Log.e("TEST", "HDPService Created");

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
            // Bluetooth adapter isn't available.  The client of the service is supposed to
            // verify that it is available and activate before invoking this service.
            stopSelf();
            return;
        }
        if (!mBluetoothAdapter.getProfileProxy(this, mBluetoothServiceListener,
                BluetoothProfile.HEALTH)) {
            Toast.makeText(this, "bluetooth_health_profile_not_available", 
                    Toast.LENGTH_LONG);
            stopSelf();
            return;
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "BluetoothHDPService is running.");
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    };

    // Register health application through the Bluetooth Health API.
    private void registerApp(int dataType) {
        Log.e(TAG, "registerApp()");
        mBluetoothHealth.registerSinkAppConfiguration(TAG, dataType, mHealthCallback);
    }

    // Unregister health application through the Bluetooth Health API.
    private void unregisterApp() {
        Log.e(TAG, "unregisterApp()");
        mBluetoothHealth.unregisterAppConfiguration(mHealthAppConfig);
    }

    // Connect channel through the Bluetooth Health API.
    private void connectChannel() {
        Log.i(TAG, "connectChannel()");
        mBluetoothHealth.connectChannelToSource(mDevice, mHealthAppConfig);
    }

    // Disconnect channel through the Bluetooth Health API.
    private void disconnectChannel() {
        Log.i(TAG, "disconnectChannel()");
        mBluetoothHealth.disconnectChannel(mDevice, mHealthAppConfig, mChannelId);
    }

    // Callbacks to handle connection set up and disconnection clean up.
    private final BluetoothProfile.ServiceListener mBluetoothServiceListener =
            new BluetoothProfile.ServiceListener() {
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (profile == BluetoothProfile.HEALTH) {
                mBluetoothHealth = (BluetoothHealth) proxy;
                if (Log.isLoggable(TAG, Log.DEBUG))
                    Log.d(TAG, "onServiceConnected to profile: " + profile);
            }
        }

        public void onServiceDisconnected(int profile) {
            if (profile == BluetoothProfile.HEALTH) {
                mBluetoothHealth = null;
            }
        }
    };

    private final BluetoothHealthCallback mHealthCallback = new BluetoothHealthCallback() {
        // Callback to handle application registration and unregistration events.  The service
        // passes the status back to the UI client.
        public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
                int status) {
            if (status == BluetoothHealth.APP_CONFIG_REGISTRATION_FAILURE) {
                mHealthAppConfig = null;
                sendMessage(STATUS_HEALTH_APP_REG, RESULT_FAIL);
            } else if (status == BluetoothHealth.APP_CONFIG_REGISTRATION_SUCCESS) {
                mHealthAppConfig = config;
                sendMessage(STATUS_HEALTH_APP_REG, RESULT_OK);
            } else if (status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_FAILURE ||
                    status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS) {
                sendMessage(STATUS_HEALTH_APP_UNREG,
                        status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS ?
                        RESULT_OK : RESULT_FAIL);
            }
        }

        // Callback to handle channel connection state changes.
        // Note that the logic of the state machine may need to be modified based on the HDP device.
        // When the HDP device is connected, the received file descriptor is passed to the
        // ReadThread to read the content.
        public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
                BluetoothDevice device, int prevState, int newState, ParcelFileDescriptor fd,
                int channelId) {

            Log.e("Read Thread", "Start If Statements");
            Log.e("Read Thread", "prevState: " + prevState);
            Log.e("Read Thread", "newState: " + newState);

            if (Log.isLoggable(TAG, Log.DEBUG))
                Log.d(TAG, String.format("prevState\t%d ----------> newState\t%d",
                        prevState, newState));

//            if (prevState != BluetoothHealth.STATE_CHANNEL_CONNECTED &&
//                    newState == BluetoothHealth.STATE_CHANNEL_CONNECTED) {

            if (prevState == BluetoothHealth.STATE_CHANNEL_DISCONNECTED &&
                    newState == BluetoothHealth.STATE_CHANNEL_CONNECTED) {
                if (config.equals(mHealthAppConfig)) {
                    mChannelId = channelId;
                    sendMessage(STATUS_CREATE_CHANNEL, RESULT_OK);
                    Log.e("Read Thread", "Read  Start 1");
                    (new ReadThread(fd)).start();
                } else {
                    Log.e("Read Thread", "Status Create Channel Fail 1");
                    sendMessage(STATUS_CREATE_CHANNEL, RESULT_FAIL);
                }
            } else if (prevState == BluetoothHealth.STATE_CHANNEL_CONNECTING &&
                       newState == BluetoothHealth.STATE_CHANNEL_DISCONNECTED) {
                sendMessage(STATUS_CREATE_CHANNEL, RESULT_FAIL);
                Log.e("Read Thread", "Status Create Channel Fail 2");
            } else if (newState == BluetoothHealth.STATE_CHANNEL_DISCONNECTED) {
                if (config.equals(mHealthAppConfig)) {
                    sendMessage(STATUS_DESTROY_CHANNEL, RESULT_OK);
                    Log.e("Read Thread", "Status Disconnect OK");
                } else {
                    sendMessage(STATUS_DESTROY_CHANNEL, RESULT_FAIL);
                    Log.e("Read Thread", "Status Disconnect FAIL");
                }
            }else if (prevState == BluetoothHealth.STATE_CHANNEL_CONNECTING && newState == BluetoothHealth.STATE_CHANNEL_CONNECTED) {
                if (config.equals(mHealthAppConfig)) {
                    mChannelId = channelId;
                    sendMessage(STATUS_CREATE_CHANNEL, RESULT_OK);
                    Log.e("Read Thread", "Read  Start 2");
                    (new ReadThread(fd)).start();
                } else {
                    sendMessage(STATUS_CREATE_CHANNEL, RESULT_FAIL);
                    Log.e("Read Thread", "Status Create Channel Fail 3");
                }
            }
        }
    };

    // Sends an update message to registered UI client.
    private void sendMessage(int what, int value) {
        if (mClient == null) {
            Log.d(TAG, "No clients registered.");
            return;
        }

        try {
            mClient.send(Message.obtain(null, what, value, 0));
        } catch (RemoteException e) {
            // Unable to reach client.
            e.printStackTrace();
        }
    }

    public String byte2hex(byte[] b){
     // String Buffer can be used instead
       String hs = "";
       String stmp = "";

       for (int n = 0; n < b.length; n++){
          stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));

          if (stmp.length() == 1){
             hs = hs + "0" + stmp;
          }
          else{
             hs = hs + stmp;
          }
          if (n < b.length - 1){
             hs = hs + "";
          }
       }

       return hs;
    }

    public static int byteToUnsignedInt(byte b) {
        return 0x00 << 24 | b & 0xff;
    }

    public static int toInt(byte[] bytes) {
          int ret = 0;
          for (int i=0; i<4 && i<bytes.length; i++) {
            ret <<= 8;
            ret |= (int)bytes[i] & 0xFF;
          }
          return ret;
    }

    // Thread to read incoming data received from the HDP device.  This sample application merely
    // reads the raw byte from the incoming file descriptor.  The data should be interpreted using
    // a health manager which implements the IEEE 11073-xxxxx specifications.
    private class ReadThread extends Thread {
        private ParcelFileDescriptor mFd;

        public ReadThread(ParcelFileDescriptor fd) {
            super();
            mFd = fd;
        }

        @Override
        public void run() {
            Log.e("TEST", "Read Data 1");
            FileInputStream fis = new FileInputStream(mFd.getFileDescriptor());
            final byte data[] = new byte[200];
            Log.i(TAG, "Read Data 2");
            try {
                while(fis.read(data) > -1) {
                    // At this point, the application can pass the raw data to a parser that
                    // has implemented the IEEE 11073-xxxxx specifications.  Instead, this sample
                    // simply indicates that some data has been received.

                    Log.i(TAG, "INBOUND");
                    String test = byte2hex(data);
                    Log.i(TAG, test);

                     if (data[0] != (byte) 0x00)
                     {

                         if(data[0] == (byte) 0xE2){
                             Log.i(TAG, "E2 - Association Request");
                             count = 1;

                             (new WriteThread(mFd)).start();
                             try {
                                 sleep(100);
                             } catch (InterruptedException e) {
                                 e.printStackTrace();
                             }
                             count = 2;
                             (new WriteThread(mFd)).start();
                         }
                         else if (data[0] == (byte)0xE7){
                             Log.i(TAG, "E7 - Data Given");


                             if(data[3] != (byte)0xda){

                                 invoke[0] = data[6];
                                 invoke[1] = data[7];

                                    Log.i(TAG, "E7 - Reading?");
                                    ByteBuffer sys = ByteBuffer.allocate(2);
                                     sys.order(ByteOrder.LITTLE_ENDIAN);
                                     sys.put(data[45]);
                                     sys.put(data[46]);
                                     short sysVal = sys.getShort(0);
                                     Log.i(TAG, " Sys - "+sysVal);

                                    ByteBuffer dia = ByteBuffer.allocate(2);
                                     dia.order(ByteOrder.LITTLE_ENDIAN);
                                     dia.put(data[47]);
                                     dia.put(data[48]);
                                     short diaVal = dia.getShort(0);
                                     Log.i(TAG, " Dia - "+diaVal);

                                     sendMessage(9919, diaVal);
                                     sendMessage(9920, sysVal);



                                   for(int i=0; i<(data.length-2); i++){
                                     ByteBuffer bb = ByteBuffer.allocate(2);
                                     bb.order(ByteOrder.LITTLE_ENDIAN);
                                     bb.put(data[i]);
                                     bb.put(data[i+1]);
                                     short shortVal = bb.getShort(0);
                                     Log.i(TAG, i+" Short Val - "+shortVal);

                                 }

                                   count = 3; 
                                   //set invoke id so get correct response 
                                   (new WriteThread(mFd)).start();
                             }
                             //parse data!!
                         }
                         else if (data[0] == (byte) 0xE4)
                         {
                             //count = 4;
                            // (new WriteThread(mFd)).start();
                         }
                         //zero out the data
                         for (int i = 0; i < data.length; i++){
                             data[i] = (byte) 0x00;
                         }
                     }
                     sendMessage(STATUS_READ_DATA, 0);
                }
            } catch(IOException ioe) {}
            if (mFd != null) {
                try {
                    mFd.close();
                } catch (IOException e) { /* Do nothing. */ }
            }
            sendMessage(STATUS_READ_DATA_DONE, 0);
        }
    }

    private class WriteThread extends Thread {
        private ParcelFileDescriptor mFd;

        public WriteThread(ParcelFileDescriptor fd) {
            super();
            mFd = fd;
        }

        @Override
        public void run() {
            FileOutputStream fos = new FileOutputStream(mFd.getFileDescriptor());
            final byte data_AR[] = new byte[] {         (byte) 0xE3, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x2C, 
                                                        (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x50, (byte) 0x79,
                                                        (byte) 0x00, (byte) 0x26,
                                                        (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x80, (byte) 0x00,
                                                        (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x08,  //bt add for phone, can be automate in the future
                                                        (byte) 0x3C, (byte) 0x5A, (byte) 0x37, (byte) 0xFF, 
                                                        (byte) 0xFE, (byte) 0x95, (byte) 0xEE, (byte) 0xE3,
                                                        (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x00, 
                                                        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
            final byte data_DR[] = new byte[] {         (byte) 0xE7, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x12,
                                                        (byte) 0x00, (byte) 0x10,
                                                        (byte) 0x00, (byte) 0x24,
                                                        (byte) 0x02, (byte) 0x01,
                                                        (byte) 0x00, (byte) 0x0A,
                                                        (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x0D, (byte) 0x1D,
                                                        (byte) 0x00, (byte) 0x00 };

            final byte get_MDS[] = new byte[] {         (byte) 0xE7, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x0E,
                                                        (byte) 0x00, (byte) 0x0C,
                                                        (byte) 0x00, (byte) 0x24,
                                                        (byte) 0x01, (byte) 0x03,
                                                        (byte) 0x00, (byte) 0x06,
                                                        (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x00 };

            final byte data_RR[] = new byte[] {         (byte) 0xE5, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x02,
                                                        (byte) 0x00, (byte) 0x00 };

//            final byte data_RRQ[] = new byte[] {        (byte) 0xE4, (byte) 0x00,
//                                                        (byte) 0x00, (byte) 0x02,
//                                                        (byte) 0x00, (byte) 0x00 };
//
//            final byte data_ABORT[] = new byte[] {      (byte) 0xE6, (byte) 0x00,
//                                                        (byte) 0x00, (byte) 0x02,
//                                                        (byte) 0x00, (byte) 0x00 };
            try {
                Log.i(TAG, String.valueOf(count));
                if (count == 1)
                {
                    fos.write(data_AR);
                    Log.i(TAG, "Association Responded!");
                }  
                else if (count == 2)
                {
                    fos.write(get_MDS);
                    Log.i(TAG, "Get MDS object attributes!");
                }
                else if (count == 3) 
                {
                    fos.write(data_DR);
                    Log.i(TAG, "Data Responsed!");
                }
                else if (count == 4)
                {
                    fos.write(data_RR);
                    Log.i(TAG, "Data Released!");
                }
            } catch(IOException ioe) {}
        }

    }
}

答案 1 :(得分:1)

数据缓冲区包含2byte值和4byte值。正如您在pdf中看到的那样,可能是短路和整数。你是否说明了这一点?

0xE7 0x00           APDU CHOICE Type (PrstApdu)  
0x00 0x84           CHOICE.length= 132  
0x00 0x82           OCTET STRING.length = 130  
0x00 0x01           invoke-id (differentiates this message from any other outstanding)  
0x01 0x01           CHOICE (Remote Operation Invoke | Confirmed Event Report)  
0x00 0x7C           CHOICE.length = 124  
0x00 0x00           obj-handle = 0 (MDS object)  
0x00 0x00 0x10 0x15 event-time (set to 0xFFFFFFFF if RelativeTime is not supported)  
0x0D 0x1C           event-type = MDC_NOTI_CONFIG   

答案 2 :(得分:1)

@ Jieqin - 太棒了,你也得到了它:)。

将此粘贴​​到

块下的阅读主题中
else if (data[0] == (byte)0xE7){
Log.i(TAG, "E7");
//work for legacy device...
if (data[18] == (byte) 0x0d && data[19] == (byte) 0x1d)  //fixed report

解析您的代理商答案 - 如果有效,请评价我的提示:)

else if (data[18] == (byte) 0x0d && data[19] == (byte) 0x1f)  //mp var report
                        {
                                count = 999; 
                                //set invoke id so get correct response
                                invoke = new byte[] { data[6], data[7] };
                                //write back response
                                (new WriteThread(mFd)).start();     
                                //parse data!!
                                int length = data[21];
                                Log.i(TAG, "length is " + length);
                                // check data-req-id 
                                int report_no = data[25];
                                int number_of_data_packets = data[29];
                                //packet_start starts from handle 0 byte
                                int packet_start = 36;
                                final int SYS_DIA_MAP_DATA = 1;
                                final int PULSE_DATA = 2;
                                final int STATUS = 3;
                                for (int i = 0; i < number_of_data_packets; i++)
                                {
                                    int obj_handle = data[packet_start+1];
                                    switch (obj_handle)
                                    {
                                    case SYS_DIA_MAP_DATA:
                                        int sys = byteToUnsignedInt(data[packet_start+9]);
                                        int dia = byteToUnsignedInt(data[packet_start+11]);
                                        int map = byteToUnsignedInt(data[packet_start+13]);

                                        Log.i(TAG, "sys is "+ sys);
                                        sendMessage(RECEIVED_SYS, sys);
                                        Log.i(TAG, "dia is "+ dia);
                                        sendMessage(RECEIVED_DIA, dia);
                                        Log.i(TAG, "map is "+ map);

                                        break;
                                    case PULSE_DATA:
                                        //parse
                                        int pulse = byteToUnsignedInt(data[packet_start+5]);
                                        Log.i(TAG, "pulse is " + pulse);
                                        sendMessage(RECEIVED_PUL, pulse);
                                        break;
                                    case STATUS:
                                        //need more signal
                                        Log.i(TAG, "STATUS");
                                        break;
                                    }
                                    packet_start += byteToUnsignedInt(data[packet_start+3]) + 4;   //4 = ignore beginning four bytes
                                }                               
                        }

答案 3 :(得分:1)

afaik你必须在自动或推送上传之间做出选择。

如果自动正常工作并且您可以读取数据,那么只需禁用自动上传并在测量后直接通过上传按钮将数据推送到您的设备......

问候

答案 4 :(得分:0)

您可能应该将data_AR中正确的设备地址发送回设备 - 在您的情况下:002209225835c328

因此你应该交换:

(byte) 0x00, (byte) 0x08,  //bt add for phone, can be automate in the future

(byte) 0x3C, (byte) 0x5A, (byte) 0x37, (byte) 0xFF, 

(byte) 0xFE, (byte) 0x95, (byte) 0xEE, (byte) 0xE3,

使用:

(byte) 0x00, (byte) 0x08,  //bt add for phone, can be automate in the future

(byte) 0x00, (byte) 0x22, (byte) 0x09, (byte) 0x22, 

(byte) 0x58, (byte) 0x35, (byte) 0xc3, (byte) 0x28,

并且还使用了 0x00 0x03 result = accepted-unknown-config喜欢

final byte data_AR[] = new byte[] {         
             (byte) 0xE3, (byte) 0x00,
             (byte) 0x00, (byte) 0x2C, 
             (byte) 0x00, (byte) 0x03,

修改

我犯了错误 - 地址不是您的BPM-DEvice而是您的手机... 要从48位MAC地址中获取EUI 64位地址,只需在中间拆分并添加0xFF 0xFE,如: BT 48bit MAC [00:11:22:33:44:55]成为

EUI 64 Bit [00:11:22:FF:FE:33:44:55] 

我很抱歉

答案 5 :(得分:0)

我从这里开始阅读IEEE:IEEE 11073-20601-2008

请参阅CLause 7.4.4上的第57页:

  

代理发起的测量数据传输由代理发送,   例如,由于采取了新的测量结果。   经理启动的测量数据传输是明确的   经理通过发出命令(即MDS-Data-Request)请求   指示代理开始或停止发送测量数据。   取决于代理的能力,这个时间段   报告模式是活动的是可配置的(例如,固定期间或总是   虽然相关)。经理应支持收到代理人和   管理员发起的测量数据从代理传输。一个   代理人可以支持生成一个或两个代理人和   经理发起的测量数据传输。在代理人和   经理发起的测量数据传输,事件报告   用于携带测量数据。