簡體   English   中英

解析從藍牙HDP設備接收的原始數據

[英]Parsing raw data received from bluetooth HDP device

我正在嘗試從連續健康聯盟認證的歐姆龍708-BT血壓監測儀中讀取數據。 我正在關注這個藍牙HDP應用程序的例子。 我正在設法連接到設備並以字節格式檢索數據,但無法解析數據以獲取所需的值。 我正在嘗試遵循本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):

任何幫助將非常感激。 提前致謝。

我設法解決了這個問題。 我遇到的主要問題是我只接受了一次血壓讀數,然后繼續按下上傳。 這會上傳一些有關顯示器的信息,但不包括血壓讀數。 一旦我知道了這一點,我就有其他一些較小的錯誤要解決,但沒有太復雜。 最終工作服務的代碼如下。

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) {}
        }

    }
}

數據緩沖區包含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   

@ 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
                                }                               
                        }

afaik你必須在自動或推送上傳之間進行選擇。

如果自動工作並且您可以讀取數據,則只需禁用自動上傳並在測量后直接通過上傳按鈕將數據推送到您的設備...

問候

您可能應該將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] 

我很抱歉

我從這里讀IEEE: IEEE 11073-20601-2008

請查看CLause 7.4.4的第57頁:

代理發起的測量數據傳輸由代理發送,例如,作為采取的新測量的結果。 管理者通過發出命令(即,MDS-數據請求)來指示代理開始或停止發送測量數據來明確地請求管理者發起的測量數據傳輸。 取決於代理的能力,該報告模式活動時的時間段是可配置的(例如,固定時段或始終在關聯時)。 經理應支持從代理收到代理和經理發起的測量數據傳輸。 代理可以支持代理和管理器發起的測量數據傳輸中的一個或兩個的生成。 在代理和管理器發起的測量數據傳輸中,事件報告用於攜帶測量數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM