记录学习蓝牙控制硬件

发布时间 2023-12-19 09:32:54作者: 张学涛

今天记录的是mesh 组网

蓝牙大致步骤:扫描周围设备、扫描到设备后,连接并获取地址、入网、订阅、发送接收消息

目前定义的是16bit 但是手机厂商定义的是32bit

1.扫描

/**
 * Start scanning for Bluetooth devices.
 *    记得申请蓝牙权限
 * @param filterUuid UUID to filter scan results with
 */
public void startScan(final UUID filterUuid, boolean auto) {
    mFilterUuid = filterUuid;
    Log.e(TAG, "mScannerStateLiveData: 6" );
    if (mScannerStateLiveData.isScanning()) {
        return;
    }
 
    if (mFilterUuid.equals(BleMeshManager.MESH_PROXY_UUID)) {
        final MeshNetwork network = mMeshManagerApi.getMeshNetwork();
        if (network != null) {
            if (!network.getNetKeys().isEmpty()) {
                mNetworkId = mMeshManagerApi.generateNetworkId(network.getNetKeys().get(0).getKey());
            }
        }
    }
    Log.e(TAG, "mScannerStateLiveData: 7" );
    mScannerStateLiveData.scanningStarted();
    //Scanning settings
    final ScanSettings settings = new ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            // Refresh the devices list every second
            .setReportDelay(0)
            // Hardware filtering has some issues on selected devices
            .setUseHardwareFilteringIfSupported(false)
            // Samsung S6 and S6 Edge report equal value of RSSI for all devices. In this app we ignore the RSSI.
            /*.setUseHardwareBatchingIfSupported(false)*/
            .build();
 
    //Let's use the filter to scan only for unprovisioned mesh nodes.
    final List<ScanFilter> filters = new ArrayList<>();
    filters.add(new ScanFilter.Builder().setServiceUuid(new ParcelUuid((filterUuid))).build());
 
    final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
    Log.e(TAG, "startScan: 开始扫描" );
    scanner.startScan(filters, settings, mScanCallbacks);
}

2.连接

@SuppressLint("RestrictedApi")
private void connect(final ExtendedBluetoothDevice extendedBluetoothDevice) {
 
    /**
     * 蓝牙     --根据UUID中的型号ID
     * DMX      --根据品牌-系列-模式
     * 2.4G     --单色温,双色温,全彩
     */
    String uuid = ((UnprovisionedBeacon) selectedBluetoothDevice.getBeacon()).getUuid().toString().replace("-", "");
    String[] stringArray = OrderUtils.hexStringToStringArray(uuid);
    //型号byte 10 ~ 12    表示型号
    String modelFileName = stringArray[10] + stringArray[11] + stringArray[12];
    Log.e(TAG, "modelFileName: " + modelFileName);
 
    dataJson = dataJsonCommonDaoUtils.queryBykey(modelFileName);
    if (dataJson == null) {
        ConfirmDialog confirmDialog = new ConfirmDialog(mContext, R.style.dialog, "没有该型号的配置文件:\n" + modelFileName, getResources().getString(R.string.account_confirm));
        confirmDialog.show();
        hideCustomProgress();
        cancleHandlerProvisioning();
        return;
    }
    if (fromType == 1 || fromType == 2) {
        String json = dataJson.getDataJson();
        if (!json.contains("FUNCTION")) {
            ConfirmDialog confirmDialog = new ConfirmDialog(mContext, R.style.dialog, "请添加控制盒类型的配置文件\n", getResources().getString(R.string.account_confirm));
            confirmDialog.show();
            hideCustomProgress();
            cancleHandlerProvisioning();
            return;
        }
    }
 
    nextChBlue = getNextCHBlue();
    if (nextChBlue == -1) {//如果nextChBlue==-1,说明蓝牙地址1-512已将占完,直接return;
        cancleHandlerProvisioning();
        return;
    }
 
    showCustomProgress(getResources().getString(R.string.ble_provisioning) + (addIndex + 1) + "/" + mSelectCommonList.size());
 
    scannerViewModel.getScannerRepository().stopScan();
 
    provisioningViewModel.connect(this, extendedBluetoothDevice, false);
 
    //监听连接状态
    provisioningViewModel.getConnectionState().observe(this, new Observer<String>() {
        @Override
        public void onChanged(@Nullable String s) {
            Log.e(TAG, "getConnectionState: " + s);
        }
    });
    //监听是否连接
    provisioningViewModel.isConnected().observe(this, connected -> {
        final boolean isComplete = provisioningViewModel.isProvisioningComplete();
        if (isComplete) {
            return;
        }
 
        if (connected != null) {
            if (connected) {
                Log.e(TAG, "isConnected: " + "连接成功");
                handlerProvisioning.sendEmptyMessageDelayed(1, 4000);
            } else {
                Log.e(TAG, "isConnected: " + "连接失败");
            }
        } else {
            Log.e(TAG, "isConnected: " + "未连接");
        }
 
    });
 
    //监听设备信息
    provisioningViewModel.isDeviceReady().observe(this, deviceReady -> {
        if (provisioningViewModel.getBleMeshManager().isDeviceReady()) {
            Log.e(TAG, "isDeviceReady:");
            final boolean isComplete = provisioningViewModel.isProvisioningComplete();
            if (isComplete) {
                setupProvisionerStateObservers();
                return;
            }
        }
    });
 
    //监听重连
    provisioningViewModel.isReconnecting().observe(this, isReconnecting -> {
        Log.e(TAG, "isReconnecting:");
        if (isReconnecting != null && isReconnecting) {
            provisioningViewModel.getUnprovisionedMeshNode().removeObservers(this);
        } else {
            setResultIntent();
        }
    });
 
    //监听key
    provisioningViewModel.getNetworkLiveData().observe(this, meshNetworkLiveData -> {
 
        final ApplicationKey applicationKey = meshNetworkLiveData.getSelectedAppKey();
        Log.e(TAG, "getNetworkLiveData:Key:" + MeshParserUtils.bytesToHex(applicationKey.getKey(), false));
        Log.e(TAG, "getNetworkLiveData: Address:" + getString(R.string.ble_hex_format, String.format(Locale.US, "%04X", meshNetworkLiveData.getMeshNetwork().getUnicastAddress())));
 
        // 获取已选择的app key
        //appKeyView.setText(MeshParserUtils.bytesToHex(applicationKey.getKey(), false));
//            Log.e("TAG", "onCreate: " + MeshParserUtils.bytesToHex(applicationKey.getKey(), false) );
 
//            unicastAddressView.setText(getString(R.string.ble_hex_format,
//                    String.format(Locale.US, "%04X", meshNetworkLiveData.getMeshNetwork().getUnicastAddress())));
    });
 
    //监听设备识别
    provisioningViewModel.getUnprovisionedMeshNode().observe(this, meshNode -> {
        Log.e(TAG, "getUnprovisionedMeshNode:meshNode=" + (meshNode == null));
        if (meshNode != null) {
            final ProvisioningCapabilities capabilities = meshNode.getProvisioningCapabilities();
            Log.e(TAG, "getUnprovisionedMeshNode:capabilities=" + (capabilities == null));
            if (capabilities != null) {
                final MeshNetwork network = provisioningViewModel.getNetworkLiveData().getMeshNetwork();
                if (network != null) {
                    try {
                        final int elementCount = capabilities.getNumberOfElements();
                        final Provisioner provisioner = network.getSelectedProvisioner();
                        final int unicast = network.nextAvailableUnicastAddress(elementCount, provisioner);
                        network.assignUnicastAddress(unicast);
                    } catch (IllegalArgumentException ex) {
                        ToastUtil.showToast(mContext, ex.getMessage());
                    }
                }
            }
        }
    });
}

3.选择模型和节点

//选择节点
public ProvisionedMeshNode setSelectNode(String controlAddress) {
    MeshNetwork network = Consts.sharedViewModel.getNetworkLiveData().getMeshNetwork();
    ProvisionedMeshNode node = network.getNode(Integer.parseInt(controlAddress));
    if (node != null) {
        Consts.sharedViewModel.setSelectedMeshNode(node);
        mElements.clear();
        mElements.addAll(node.getElements().values());
        tag2:
        for (int i = 0; i < mElements.size(); i++) {
            List<MeshModel> models = new ArrayList<>(mElements.get(i).getMeshModels().values());
            tag1:
            for (int j = 0; j < models.size(); j++) {
                if (models.get(j) instanceof VendorModel) {
                    Consts.modelConfigurationViewModel.setSelectedElement(mElements.get(i));
                    Consts.modelConfigurationViewModel.setSelectedModel(models.get(j));
                    break tag2;
                }
            }
        }
    }
    return node;
}

4.

//入网
@SuppressLint("RestrictedApi")
public void provisionClick() {
    final UnprovisionedMeshNode node = provisioningViewModel.getUnprovisionedMeshNode().getValue();
    Log.e(TAG, "isConnected: ((((((((((((( " + (node == null));
    if (node == null) {
        Log.e(TAG, "isConnected: " + provisioningViewModel.getNetworkLiveData().getNodeName());
        provisioningViewModel.getNrfMeshRepository().identifyNode(selectedBluetoothDevice);
        return;
    }
    //配置入网
    if (node.getProvisioningCapabilities() != null) {
        Log.e(TAG, "onCreate: " + (node.getProvisioningCapabilities().getAvailableOOBTypes().size() == 1 &&
                node.getProvisioningCapabilities().getAvailableOOBTypes().get(0) == AuthenticationOOBMethods.NO_OOB_AUTHENTICATION));
        if (node.getProvisioningCapabilities().getAvailableOOBTypes().size() == 1 &&
                node.getProvisioningCapabilities().getAvailableOOBTypes().get(0) == AuthenticationOOBMethods.NO_OOB_AUTHENTICATION) {
            onNoOOBSelected();
        } else {
//               final DialogFragmentSelectOOBType fragmentSelectOOBType = DialogFragmentSelectOOBType.newInstance(meshNode.getProvisioningCapabilities());
//               fragmentSelectOOBType.show(getSupportFragmentManager(), null);
        }
    }
}
 
 
@SuppressLint("RestrictedApi")
public void setupProvisionerStateObservers() {
    provisioningViewModel.getProvisioningStatus().observe(this, provisioningStateLiveData -> {
        if (provisioningStateLiveData != null) {
            final ProvisionerProgress provisionerProgress = provisioningStateLiveData.getProvisionerProgress();
            provisioningStateLiveData.getStateList();
            if (provisionerProgress != null) {
                final ProvisionerStates state = provisionerProgress.getState();
                Log.e(TAG, "setupProvisionerStateObservers: state:" + state);
                switch (state) {
                    case PROVISIONING_CAPABILITIES:
                        Log.e("TAG", "PROVISIONING_CAPABILITIES: " + provisioningViewModel.getNetworkLiveData().getMeshNetwork().getUnicastAddress());
                        String address = String.format(Locale.US, "%04X", provisioningViewModel.getNetworkLiveData().getMeshNetwork().getUnicastAddress());
                        addressMap.put(selectedBluetoothDevice.getAddress(), address);
                        break;
                    case PROVISIONING_FAILED://失败
//                        if (getSupportFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_PROVISIONING_FAILED) == null) {
//                            final String statusMessage = ProvisioningFailedState.parseProvisioningFailure(getApplicationContext(), provisionerProgress.getStatusReceived());
//                            DialogFragmentProvisioningFailedError message = DialogFragmentProvisioningFailedError.newInstance(getString(R.string.ble_title_error_provisioning_failed), statusMessage);
//                            message.show(getSupportFragmentManager(), DIALOG_FRAGMENT_PROVISIONING_FAILED);
//                        }
                        break;
                    case PROVISIONING_AUTHENTICATION_STATIC_OOB_WAITING:
                    case PROVISIONING_AUTHENTICATION_OUTPUT_OOB_WAITING:
                    case PROVISIONING_AUTHENTICATION_INPUT_OOB_WAITING:
//                        if (getSupportFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_AUTH_INPUT_TAG) == null) {
//                            DialogFragmentAuthenticationInput dialogFragmentAuthenticationInput = DialogFragmentAuthenticationInput.
//                                    newInstance(mViewModel.getUnprovisionedMeshNode().getValue());
//                            dialogFragmentAuthenticationInput.show(getSupportFragmentManager(), DIALOG_FRAGMENT_AUTH_INPUT_TAG);
//                        }
                        break;
                    case PROVISIONING_AUTHENTICATION_INPUT_ENTERED:
//                        final DialogFragmentAuthenticationInput fragment = (DialogFragmentAuthenticationInput) getSupportFragmentManager().
//                                findFragmentByTag(DIALOG_FRAGMENT_AUTH_INPUT_TAG);
//                        if (fragment != null) {
//                            fragment.dismiss();
//                        }
                        break;
                    case PROVISIONING_COMPLETE:
                    case NETWORK_TRANSMIT_STATUS_RECEIVED:
//                        if (getSupportFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_CONFIGURATION_STATUS) == null) {
//                            DialogFragmentConfigurationComplete fragmentConfigComplete = DialogFragmentConfigurationComplete.
//                                    newInstance(getString(R.string.title_configuration_compete), getString(R.string.configuration_complete_summary));
//                            fragmentConfigComplete.show(getSupportFragmentManager(), DIALOG_FRAGMENT_CONFIGURATION_STATUS);
//                        }
                        Log.e(TAG, "setupProvisionerStateObservers: " + "PROVISIONING_COMPLETE");
                        handlerProvisioning.sendEmptyMessageDelayed(3, 3000);
                        break;
                    case PROVISIONER_UNASSIGNED:
                        setResultIntent();
                        break;
                    default:
                        break;
                }
            }
        }
    });
 
}
 
 public void onNoOOBSelected() {
        final UnprovisionedMeshNode node = provisioningViewModel.getUnprovisionedMeshNode().getValue();
        if (node != null) {
            try {
                node.setNodeName(provisioningViewModel.getNetworkLiveData().getNodeName());
                setupProvisionerStateObservers();
                provisioningViewModel.getMeshManagerApi().startProvisioning(node);
            } catch (IllegalArgumentException ex) {
                ToastUtil.showToast(mContext, ex.getMessage());
            }
        }
    }

发送消息

/**
 * Send vendor model acknowledged message
 *
 * @param opcode     opcode of the message
 * @param parameters parameters of the message
 */
public void sendVendorModelMessage(final int opcode, final byte[] parameters, final boolean acknowledged) {
    final Element element = Consts.modelConfigurationViewModel.getSelectedElement().getValue();
    if (element != null) {
        final VendorModel model = (VendorModel) Consts.modelConfigurationViewModel.getSelectedModel().getValue();
        if (model != null) {
            final int appKeyIndex = Consts.modelConfigurationViewModel.getMeshManagerApi().getMeshNetwork().getAppKey(0).getKeyIndex();
            // final int appKeyIndex = model.getBoundAppKeyIndexes().get(0);
            final ApplicationKey appKey = Consts.modelConfigurationViewModel.getNetworkLiveData().getMeshNetwork().getAppKey(appKeyIndex);
            final MeshMessage message;
            if (acknowledged) {
                message = new VendorModelMessageAcked(appKey, model.getModelId(), model.getCompanyIdentifier(), opcode, parameters);
                int address = element.getElementAddress();
                if (lightEquipmentGroup != null && lightEquipmentGroup.getConnectMethod() == 0) {
                    address = Consts.sharedViewModel.getSelectedGroup().getValue().getAddress();
                }
                sendMessage(address, message);
            } else {
                message = new VendorModelMessageUnacked(appKey, model.getModelId(), model.getCompanyIdentifier(), opcode, parameters);
                int address = element.getElementAddress();
                if (lightEquipmentGroup != null && lightEquipmentGroup.getConnectMethod() == 0) {
                    address = Consts.sharedViewModel.getSelectedGroup().getValue().getAddress();
                }
                sendMessage(address, message);
            }
        }
    }
}
 
protected void sendMessage(final int address, @NonNull final MeshMessage meshMessage) {
    try {
        Log.e(TAG, "sendMessage: " + checkConnectivity());
        if (!checkConnectivity())
            return;
        Consts.modelConfigurationViewModel.getMeshManagerApi().createMeshPdu(address, meshMessage);
    } catch (IllegalArgumentException ex) {
        ToastUtil.showToast(mContext, getString(R.string.ble_title_error));
    }
}

订阅群组

//订阅网络群组
    public void subscribe() {
        final ProvisionedMeshNode meshNode = modelConfigurationViewModel.getSelectedMeshNode().getValue();
        Log.e(TAG, "meshNodeIsnull: " + (meshNode == null));
        if (meshNode != null) {
            final Element element = modelConfigurationViewModel.getSelectedElement().getValue();
            Log.e(TAG, "elementIsnull: " + (element == null));
            if (element != null) {
                final int elementAddress = element.getElementAddress();
                final MeshModel model = modelConfigurationViewModel.getSelectedModel().getValue();
                Log.e(TAG, "modelIsnull: " + (model == null));
                if (model != null) {
                    final int modelIdentifier = model.getModelId();
                    final MeshMessage configModelSubscriptionAdd;
                    Log.e(TAG, "group.getAddressLabel(): " + (group.getAddressLabel() == null));
                    if (group.getAddressLabel() == null) {
                        configModelSubscriptionAdd = new ConfigModelSubscriptionAdd(elementAddress, group.getAddress(), modelIdentifier);
                    } else {
                        configModelSubscriptionAdd = new ConfigModelSubscriptionVirtualAddressAdd(elementAddress, group.getAddressLabel(), modelIdentifier);
                    }
 
                    sendMessage(meshNode.getUnicastAddress(), configModelSubscriptionAdd);
 
                    handlerCheckIsConnectIndex=addIndex;
                    handlerCheckIsConnect.removeCallbacksAndMessages(0);
                    handlerCheckIsConnect.sendEmptyMessageDelayed(1,3000);
                }
            }
        }
    }

接收消息

public void onMeshMessageReceived(final int src, @NonNull final MeshMessage meshMessage) {
        final ProvisionedMeshNode node = mMeshNetwork.getNode(src);
        if (node != null)
            if (meshMessage instanceof ProxyConfigFilterStatus) {
                mProvisionedMeshNode = node;
                setSelectedMeshNode(node);
                final ProxyConfigFilterStatus status = (ProxyConfigFilterStatus) meshMessage;
                final int unicastAddress = status.getSrc();
                Log.v(TAG, "Proxy configuration source: " + MeshAddress.formatAddress(status.getSrc(), false));
                mConnectedProxyAddress.postValue(unicastAddress);
                mMeshMessageLiveData.postValue(status);
            } else if (meshMessage instanceof ConfigCompositionDataStatus) {
                final ConfigCompositionDataStatus status = (ConfigCompositionDataStatus) meshMessage;
                if (mSetupProvisionedNode) {
                    mIsCompositionDataReceived = true;
                    mProvisionedMeshNodeLiveData.postValue(node);
                    mConnectedProxyAddress.postValue(node.getUnicastAddress());
                    mProvisioningStateLiveData.onMeshNodeStateUpdated(ProvisionerStates.COMPOSITION_DATA_STATUS_RECEIVED);
                    mHandler.postDelayed(() -> {
                        Log.e(TAG, "onMeshMessageReceived: 500" );
                        final ConfigDefaultTtlGet configDefaultTtlGet = new ConfigDefaultTtlGet();
                        Log.e(TAG, "onMeshMessageReceived: 3" );
                        mMeshManagerApi.createMeshPdu(node.getUnicastAddress(), configDefaultTtlGet);
                    //}, 500);
                    }, 0);
                } else {
                    updateNode(node);
                }
            } else if (meshMessage instanceof ConfigDefaultTtlStatus) {
                final ConfigDefaultTtlStatus status = (ConfigDefaultTtlStatus) meshMessage;
                if (mSetupProvisionedNode) {
                    mIsDefaultTtlReceived = true;
                    mProvisionedMeshNodeLiveData.postValue(node);
                    mProvisioningStateLiveData.onMeshNodeStateUpdated(ProvisionerStates.DEFAULT_TTL_STATUS_RECEIVED);
                    mHandler.postDelayed(() -> {
                        Log.e(TAG, "onMeshMessageReceived: 1500" );
                        final ApplicationKey appKey = mMeshNetworkLiveData.getSelectedAppKey();
                        @SuppressLint("RestrictedApi") final int index = node.getAddedNetKeys().get(0).getIndex();
                        final NetworkKey networkKey = mMeshNetwork.getNetKeys().get(index);
                        final ConfigAppKeyAdd configAppKeyAdd = new ConfigAppKeyAdd(networkKey, appKey);
                        Log.e(TAG, "onMeshMessageReceived: 2" );
                        mMeshManagerApi.createMeshPdu(node.getUnicastAddress(), configAppKeyAdd);
                    //}, 1500);
                    }, 0);
                } else {
                    updateNode(node);
                    mMeshMessageLiveData.postValue(status);
                }
            } else if (meshMessage instanceof ConfigAppKeyStatus) {
                final ConfigAppKeyStatus status = (ConfigAppKeyStatus) meshMessage;
                if (mSetupProvisionedNode) {
                    if (status.isSuccessful()) {
                        mIsAppKeyAddCompleted = true;
                        mProvisionedMeshNodeLiveData.postValue(node);
                        mProvisioningStateLiveData.onMeshNodeStateUpdated(ProvisionerStates.APP_KEY_STATUS_RECEIVED);
                        mHandler.postDelayed(() -> {
                            final ConfigNetworkTransmitSet networkTransmitSet = new ConfigNetworkTransmitSet(2, 1);
                            Log.e(TAG, "onMeshMessageReceived: 1" );
                            mMeshManagerApi.createMeshPdu(node.getUnicastAddress(), networkTransmitSet);
                        // }, 1500);
                        }, 0);
                    }
                } else {
                    updateNode(node);
                    mMeshMessageLiveData.postValue(status);
                }
            } else if (meshMessage instanceof ConfigNetworkTransmitStatus) {
                if (mSetupProvisionedNode) {
                    mSetupProvisionedNode = false;
                    mIsNetworkRetransmitSetCompleted = true;
                    mProvisioningStateLiveData.onMeshNodeStateUpdated(ProvisionerStates.NETWORK_TRANSMIT_STATUS_RECEIVED);
                } else {
                    updateNode(node);
                    final ConfigNetworkTransmitStatus status = (ConfigNetworkTransmitStatus) meshMessage;
                    mMeshMessageLiveData.postValue(status);
                }
            } else if (meshMessage instanceof ConfigModelAppStatus) {
                if (updateNode(node)) {
                    final ConfigModelAppStatus status = (ConfigModelAppStatus) meshMessage;
                    final Element element = node.getElements().get(status.getElementAddress());
                    if (node.getElements().containsKey(status.getElementAddress())) {
                        mSelectedElement.postValue(element);
                        final MeshModel model = element.getMeshModels().get(status.getModelIdentifier());
                        mSelectedModel.postValue(model);
                    }
                }
 
            } else if (meshMessage instanceof ConfigModelPublicationStatus) {
 
                if (updateNode(node)) {
                    final ConfigModelPublicationStatus status = (ConfigModelPublicationStatus) meshMessage;
                    if (node.getElements().containsKey(status.getElementAddress())) {
                        final Element element = node.getElements().get(status.getElementAddress());
                        mSelectedElement.postValue(element);
                        final MeshModel model = element.getMeshModels().get(status.getModelIdentifier());
                        Log.e(TAG, "onMeshMessageReceived: ****************************" );
                        mSelectedModel.postValue(model);
                    }
                }
 
            } else if (meshMessage instanceof ConfigModelSubscriptionStatus) {
 
                if (updateNode(node)) {
                    final ConfigModelSubscriptionStatus status = (ConfigModelSubscriptionStatus) meshMessage;
                    if (node.getElements().containsKey(status.getElementAddress())) {
                        final Element element = node.getElements().get(status.getElementAddress());
                        mSelectedElement.postValue(element);
                        final MeshModel model = element.getMeshModels().get(status.getModelIdentifier());
                        mSelectedModel.postValue(model);
                    }
                }
 
            } else if (meshMessage instanceof ConfigNodeResetStatus) {
                mBleMeshManager.setClearCacheRequired();
                final ConfigNodeResetStatus status = (ConfigNodeResetStatus) meshMessage;
                mExtendedMeshNode.postValue(null);
                Log.e(TAG, "onMeshMessageReceived: 2" );
                loadNodes();
                mMeshMessageLiveData.postValue(status);
 
            } else if (meshMessage instanceof ConfigRelayStatus) {
                if (updateNode(node)) {
                    final ConfigRelayStatus status = (ConfigRelayStatus) meshMessage;
                    mMeshMessageLiveData.postValue(status);
                }
 
            } else if (meshMessage instanceof ConfigProxyStatus) {
                if (updateNode(node)) {
                    final ConfigProxyStatus status = (ConfigProxyStatus) meshMessage;
                    mMeshMessageLiveData.postValue(status);
                }
 
            } else if (meshMessage instanceof GenericOnOffStatus) {
                if (updateNode(node)) {
                    final GenericOnOffStatus status = (GenericOnOffStatus) meshMessage;
                    if (node.getElements().containsKey(status.getSrcAddress())) {
                        final Element element = node.getElements().get(status.getSrcAddress());
                        mSelectedElement.postValue(element);
                        final MeshModel model = element.getMeshModels().get((int) SigModelParser.GENERIC_ON_OFF_SERVER);
                        mSelectedModel.postValue(model);
                    }
                }
            } else if (meshMessage instanceof GenericLevelStatus) {
 
                if (updateNode(node)) {
                    final GenericLevelStatus status = (GenericLevelStatus) meshMessage;
                    if (node.getElements().containsKey(status.getSrcAddress())) {
                        final Element element = node.getElements().get(status.getSrcAddress());
                        mSelectedElement.postValue(element);
                        final MeshModel model = element.getMeshModels().get((int) SigModelParser.GENERIC_LEVEL_SERVER);
                        mSelectedModel.postValue(model);
                    }
                }
 
            } else if (meshMessage instanceof VendorModelMessageStatus) {
 
                if (updateNode(node)) {
                    final VendorModelMessageStatus status = (VendorModelMessageStatus) meshMessage;
                    if (node.getElements().containsKey(status.getSrcAddress())) {
                        final Element element = node.getElements().get(status.getSrcAddress());
                        mSelectedElement.postValue(element);
                        final MeshModel model = element.getMeshModels().get(status.getModelIdentifier());
                        mSelectedModel.postValue(model);
                    }
                }
            }
 
        if (mMeshMessageLiveData.hasActiveObservers()) {
            mMeshMessageLiveData.postValue(meshMessage);
        }
 
        //Refresh mesh network live data
        mMeshNetworkLiveData.refresh(mMeshManagerApi.getMeshNetwork());
    }

解析数据

public static String hexStringFormatNormal1(CmdNormal cmdNormal) {
        if (cmdNormal == null) {
            return "";
        }
        /**
         * 功能码8位二进制组成功能byte
         * Bit[0]  :  0-不需要从机返回信息 /  1-需要从机返回信息
         * Bit[1]  :  0-发送 /  1-返回
         * Bit[3]  :  0-快捷指令 /  1-常规指令
         * Bit[4:3] :  0-蓝牙灯具 /  1-2.4G灯具 /  2-DMX灯具
         * Bit[6:5] :  未使用,保持0
         * Bit[7]  :  0-独立一帧 / 1-多帧数据
         */
        StringBuffer stringBufferFunction = new StringBuffer();
        CmdFunction cmdFunction = cmdNormal.getCmdFunction();
        stringBufferFunction.append(cmdFunction.getIsMultiFrame());//7位(0-独立一帧 / 1-多帧数据)
        stringBufferFunction.append("0");//6位保持0
        stringBufferFunction.append(cmdFunction.getIsSetting());//5 0-查询 / 1-设置
        //stringBufferFunction.append("0");//3位保持0
        stringBufferFunction.append(OrderUtils.numToBinary(cmdFunction.getIsDeviceType(),2));//3,4位(0-蓝牙灯具 /  1-2.4G灯具 /  2-DMX灯具)
        stringBufferFunction.append(cmdFunction.getIsFunctionNormal());//2位 (0-快捷指令 /  1-常规指令)
        stringBufferFunction.append(cmdFunction.getIsFunctionBack());//1位(0-发送 /  1-返回)
        stringBufferFunction.append(cmdFunction.getIsMachineBack());//0位(0-不需要从机返回信息 /  1-需要从机返回信息)
 
 
        //功能码二进制转10进制
        int functionTen = Integer.parseInt(stringBufferFunction.toString(), 2);
 
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(bytesToHexString(cmdNormal.getRollCode()));//滚码
        stringBuffer.append(bytesToHexString(functionTen));//功能码
 
        //地址码
        int address=cmdNormal.getAddress();
        stringBuffer.append(bytesToHexString(address>> 8 & 0xff));
        stringBuffer.append(bytesToHexString(address& 0xff));
 
        //当前帧
        stringBuffer.append(bytesToHexString(cmdNormal.getCurrentFrame()));
        //总帧
        stringBuffer.append(bytesToHexString(cmdNormal.getTotalFrame()));
        //数据模式
        stringBuffer.append(bytesToHexString(cmdNormal.getModeType()));
 
        CmdNormal.AllDataMode allDataMode=cmdNormal.getAllDataMode();
        for(CmdCode cmdCode:allDataMode.getCmdCodeList()){
            if(cmdCode.getLenth()==1){
                stringBuffer.append(bytesToHexString(cmdCode.getValue()));
            }else if(cmdCode.getLenth()==2){
                stringBuffer.append(bytesToHexString(cmdCode.getValue()>> 8 & 0xff));//高8位
                stringBuffer.append(bytesToHexString(cmdCode.getValue() & 0xff));//低8位
            }else if(cmdCode.getLenth()==4){
                stringBuffer.append(bytesToHexString(cmdCode.getValue()>> 24 & 0xff));//高24位
                stringBuffer.append(bytesToHexString(cmdCode.getValue()>> 16 & 0xff));//高16位
                stringBuffer.append(bytesToHexString(cmdCode.getValue()>> 8 & 0xff));//高8位
                stringBuffer.append(bytesToHexString(cmdCode.getValue() & 0xff));//低8位
            }else if(cmdCode.getLenth()==6){
                stringBuffer.append(bytesToHexString(cmdCode.getValue()>> 40 & 0xff));//高40位
                stringBuffer.append(bytesToHexString(cmdCode.getValue()>> 32 & 0xff));//高32位
                stringBuffer.append(bytesToHexString(cmdCode.getValue()>> 24 & 0xff));//高24位
                stringBuffer.append(bytesToHexString(cmdCode.getValue()>> 16 & 0xff));//高16位
                stringBuffer.append(bytesToHexString(cmdCode.getValue()>> 8 & 0xff));//高8位
                stringBuffer.append(bytesToHexString(cmdCode.getValue() & 0xff));//低8位
            }
        }
        return stringBuffer.toString();
    }

mesh对传输的数据进行分层次加密,网络层(Network Layer)数据通过网络密钥(Network Key)加密;应用密钥(App Key)用于加密接入层(Access Layer)数据;配置模型(Configuration Model)的数据则采用设备密钥(Device Key)进行加密