(基于Nordic)Android 蓝牙mesh协议栈问题修复之-未知model解析问题修复

5 篇文章 0 订阅
4 篇文章 0 订阅

背景

  • 首先贴上官方github地址https://github.com/NordicSemiconductor/Android-nRF-Mesh-Library
  • 本次修改基于官方SDK 2.4.1版本.
  • 阅读此文章之前,我们默认您对蓝牙mesh协议已经有了一定了解.
  • 本次修复了一个问题,是关于Nordic Android SDK解析未知model时候出错的问题.

问题分析

问题的根源是从SDK的导入导出发现的,从 Nordic SDK中导出来mesh json后发现设备的信息中model的配置信息都丢失了,如下图:
在这里插入图片描述
经过排查发现,固件里面出现了两个Nordic未知的model,最后通过与固件沟通,发现是瑞昱定义了两个sig model未被Nordic识别,从而导致model未被解析出现来,最终导致了信息丢失的情况.

通过代码排查,我们发现SDK在解析sig model的时候,如果遇到未定义的model,它最后会返回null,
代码如下:

    /**
     * Returns the Bluetooth sig model based on the model id.
     *
     * @param modelId bluetooth sig model id
     * @return SigModel
     */
    public static SigModel getSigModel(final int modelId) {
        switch (modelId) {
            case CONFIGURATION_SERVER:
                return new ConfigurationServerModel(modelId);
            case CONFIGURATION_CLIENT:
                return new ConfigurationClientModel(modelId);
            case HEALTH_SERVER_MODEL:
                return new HealthServerModel(modelId);
            case HEALTH_CLIENT_MODEL:
                return new HealthClientModel(modelId);
            case GENERIC_ON_OFF_SERVER:
                return new GenericOnOffServerModel(modelId);
            case GENERIC_ON_OFF_CLIENT:
                return new GenericOnOffClientModel(modelId);
            case GENERIC_LEVEL_SERVER:
                return new GenericLevelServerModel(modelId);
            case GENERIC_LEVEL_CLIENT:
                return new GenericLevelClientModel(modelId);
            case GENERIC_DEFAULT_TRANSITION_TIME_SERVER:
                return new GenericDefaultTransitionTimeServer(modelId);
            case GENERIC_DEFAULT_TRANSITION_TIME_CLIENT:
                return new GenericDefaultTransitionTimeClient(modelId);
            case GENERIC_POWER_ON_OFF_SERVER:
                return new GenericPowerOnOffServer(modelId);
            case GENERIC_POWER_ON_OFF_SETUP_SERVER:
                return new GenericPowerOnOffSetupServer(modelId);
            case GENERIC_POWER_ON_OFF_CLIENT:
                return new GenericPowerOnOffClient(modelId);
            case GENERIC_POWER_LEVEL_SERVER:
                return new GenericPowerLevelServer(modelId);
            case GENERIC_POWER_LEVEL_SETUP_SERVER:
                return new GenericPowerLevelSetupServer(modelId);
            case GENERIC_POWER_LEVEL_CLIENT:
                return new GenericPowerLevelClient(modelId);
            case GENERIC_BATTERY_SERVER:
                return new GenericBatteryServer(modelId);
            case GENERIC_BATTERY_CLIENT:
                return new GenericBatteryClient(modelId);
            case GENERIC_LOCATION_SERVER:
                return new GenericLocationServer(modelId);
            case GENERIC_LOCATION_SETUP_SERVER:
                return new GenericLocationSetupServer(modelId);
            case GENERIC_LOCATION_CLIENT:
                return new GenericLocationClient(modelId);
            case GENERIC_ADMIN_PROPERTY_SERVER:
                return new GenericAdminPropertyServer(modelId);
            case GENERIC_MANUFACTURER_PROPERTY_SERVER:
                return new GenericManufacturerPropertyServer(modelId);
            case GENERIC_USER_PROPERTY_SERVER:
                return new GenericUserPropertyServer(modelId);
            case GENERIC_CLIENT_PROPERTY_SERVER:
                return new GenericClientPropertyServer(modelId);
            case GENERIC_PROPERTY_CLIENT:
                return new GenericPropertyClient(modelId);
            case SENSOR_SERVER:
                return new SensorServer(modelId);
            case SENSOR_SETUP_SERVER:
                return new SensorSetupServer(modelId);
            case SENSOR_CLIENT:
                return new SensorClient(modelId);
            case TIME_SERVER:
                return new TimeServer(modelId);
            case TIME_SETUP_SERVER:
                return new TimeSetupServer(modelId);
            case TIME_CLIENT:
                return new TimeClient(modelId);
            case SCENE_SERVER:
                return new SceneServer(modelId);
            case SCENE_SETUP_SERVER:
                return new SceneSetupServer(modelId);
            case SCENE_CLIENT:
                return new SceneClient(modelId);
            case SCHEDULER_SERVER:
                return new SchedulerServer(modelId);
            case SCHEDULER_SETUP_SERVER:
                return new SchedulerSetupServer(modelId);
            case SCHEDULER_CLIENT:
                return new SchedulerClient(modelId);
            case LIGHT_LIGHTNESS_SERVER:
                return new LightLightnessServer(modelId);
            case LIGHT_LIGHTNESS_SETUP_SERVER:
                return new LightLightnessSetupServer(modelId);
            case LIGHT_LIGHTNESS_CLIENT:
                return new LightLightnessClient(modelId);
            case LIGHT_CTL_SERVER:
                return new LightCtlServer(modelId);
            case LIGHT_CTL_SETUP_SERVER:
                return new LightCtlSetupServer(modelId);
            case LIGHT_CTL_CLIENT:
                return new LightCtlClient(modelId);
            case LIGHT_CTL_TEMPERATURE_SERVER:
                return new LightCtlTemperatureServer(modelId);
            case LIGHT_HSL_SERVER:
                return new LightHslServer(modelId);
            case LIGHT_HSL_SETUP_SERVER:
                return new LightHslSetupServer(modelId);
            case LIGHT_HSL_CLIENT:
                return new LightHslClient(modelId);
            case LIGHT_HSL_HUE_SERVER:
                return new LightHslHueServer(modelId);
            case LIGHT_HSL_SATURATION_SERVER:
                return new LightHslSaturationServer(modelId);
            case LIGHT_XYL_SERVER:
                return new LightXylServer(modelId);
            case LIGHT_XYL_SETUP_SERVER:
                return new LightXylSetupServer(modelId);
            case LIGHT_XYL_CLIENT:
                return new LightXylClient(modelId);
            case LIGHT_LC_SERVER:
                return new LightLcServer(modelId);
            case LIGHT_LC_SETUP_SERVER:
                return new LightLcSetupServer(modelId);
            case LIGHT_LC_CLIENT:
                return new LightLcClient(modelId);
            default: {
                Log.v(TAG, "Model ID: " + String.format(Locale.US, "%04X", modelId));
                return null;
            }
        }
    }

很明显,如果我们固件里面出现了上述未定义好的model,那么最后就会返回null,这是我们不想要的结果.然而瑞昱的两个model就未出现在上述定义之内.

修改内容

解决上述问题的方法其实很简单,通过比较IOS的SDK的做法,我们可以新建一个UnKnown Model,来接收Nordic未定义好的model.方法如下:

  1. 首先我们可以新建一个Unknown Model类
/*
 * Copyright (c) 2018, Nordic Semiconductor
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package no.nordicsemi.android.meshprovisioner.models;

import android.os.Parcel;

@SuppressWarnings("WeakerAccess")
public class UnknowModel extends SigModel {

    public static final Creator<UnknowModel> CREATOR = new Creator<UnknowModel>() {
        @Override
        public UnknowModel createFromParcel(final Parcel source) {
            return new UnknowModel(source);
        }

        @Override
        public UnknowModel[] newArray(final int size) {
            return new UnknowModel[size];
        }
    };

    public UnknowModel(final int modelId) {
        super(modelId);
    }

    private UnknowModel(final Parcel source) {
        super(source);
    }

    @Override
    public String getModelName() {
        return "Unkown model";
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(final Parcel dest, final int flags) {
        super.parcelMeshModel(dest, flags);
    }

}

2.如果我们在case里面没找到对应的model,我们在getSigModel的default里面加上UnknowModel配置.代码如下:

   /**
     * Returns the Bluetooth sig model based on the model id.
     *
     * @param modelId bluetooth sig model id
     * @return SigModel
     */
    public static SigModel getSigModel(final int modelId) {
        switch (modelId) {
            //代码省略
            default: {
                Log.v(TAG, "Model ID: " + String.format(Locale.US, "%04X", modelId));
                return new UnknowModel(modelId);
            }
        }
    }

因此,问题得到迎刃而解.

如果任何疑问,请联系邮箱:569133338@qq.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值