怎么介绍呢,一直考虑,还是从业务流程开始,1、Meshservice初始化--》2、扫描设备---》3、连接设备--》4、扫描设备--》5、设备组网
这样分析多初学者,或者刚接触CSRdemo的比较容易!
1、从MainActivity开始,第一步是在onCreate里面初始化蓝牙mesh的入口
AndroidManifest配置文件中有一下代码,不然启动MeshService失败。
<service android:name="com.csr.csrmesh2.MeshService" android:enabled="true" android:exported="false" > </service>
MeshLibraryManager.initInstance(getApplicationContext(), MeshLibraryManager.MeshChannel.BLUETOOTH,LogLevel.DEBUG);
2、在MeshLibraryManager中进行创建service连接
private MeshLibraryManager(Context context, MeshChannel channel,LogLevel lgLevel) { Log.e(TAG,"2==init===MeshLibraryManager()"); // Log message has a tag and a priority associated with it. logLevel= lgLevel; App.bus.register(this); mContext = new WeakReference<Context>(context); mCurrentChannel = channel; Intent bindIntent = new Intent(mContext.get(), MeshService.class); context.bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE); }
3、启动蓝牙,扫描蓝牙设备进行连接,重点是setBluetoothBeareEnabled接口
//激活蓝牙 private void enableBluetooth() { Log.e(TAG,"4==enable===enableBluetooth()"); mCurrentChannel = MeshChannel.BLUETOOTH; isChannelReady = false; //广播“通道没有准备好” App.bus.post(new MeshSystemEvent(MeshSystemEvent.SystemEvent.CHANNEL_NOT_READY)); mBtBearer = new BluetoothBearer(this, mContext.get()); //启动蓝牙承载***** mService.setBluetoothBearerEnabled(mBtBearer);//设置这个开始扫描蓝牙设备 } 在MeshLibraryManager中有一个MeshApiMessageHandler内部做消息处理,个人感觉有路由意思在里面meshService 都是通过这个handler消息反馈出来,还有一个BluetootHandler这个也是消息处理,后面重点结束这二个handler的关系
4、这个时候蓝牙设备已经连接上了,可以进行组网了
在demo中是这样MeshLibraryManager.getInstance().getMeshService().setDeviceDiscoveryFilterEnabled(true) 在meshService中的传入handler上报蓝牙设备数据
case DEVICE_UUID: { ParcelUuid uuid = event.data.getParcelable(MeshConstants.EXTRA_UUID); int uuidHash = event.data.getInt(MeshConstants.EXTRA_UUIDHASH_31); int rssi = event.data.getInt(MeshConstants.EXTRA_RSSI); int ttl = event.data.getInt(MeshConstants.EXTRA_TTL); boolean existing = false; for (ScanDevice info : mDiscoveredDevices) { if (uuid != null && info.uuid.equalsIgnoreCase(uuid.toString())) { info.rssi = rssi; info.ttl = ttl; // check if we already have appearance info according with the uuidHash if (mAppearances.containsKey(uuidHash)) { info.setAppearance(mAppearances.get(uuidHash)); } info.updated(); updateList(); existing = true; break; } } if (!existing) { ScanDevice info = new ScanDevice(uuid.toString().toUpperCase(), rssi, uuidHash, ttl); // check if we already have appearance info according with the uuidHash if (mAppearances.containsKey(uuidHash)) { info.setAppearance(mAppearances.get(uuidHash)); } mDiscoveredDevices.add(info); updateList(); } break; } case DEVICE_APPEARANCE: { byte[] appearance = event.data.getByteArray(MeshConstants.EXTRA_APPEARANCE); String shortName = event.data.getString(MeshConstants.EXTRA_SHORTNAME); int uuidHash = event.data.getInt(MeshConstants.EXTRA_UUIDHASH_31); for (ScanDevice info : mDiscoveredDevices) { if (info.uuidHash == uuidHash) { info.setAppearance(new AppearanceDevice(appearance, shortName)); info.updated(); } } mAppearances.put(uuidHash, new AppearanceDevice(appearance, shortName)); Log.d(TAG, "* Association Event DEVICE_APPEARANCE - mAppearances: " + mAppearances.toString()); updateList(); break; }5、有蓝牙设备进行授权组网
MeshLibraryManager.getInstance().getMeshService().associateDevice(deviceHash,authcode,isauthocode,deviceId)A、蓝牙设备授权进度
case ASSOCIATION_PROGRESS: { int progress = event.data.getInt(MeshConstants.EXTRA_PROGRESS_INFORMATION); if (!event.data.getBoolean(MeshConstants.EXTRA_CAN_BE_CANCELLED)) { runOnUiThread(new Runnable() { @Override public void run() { if (mDialog != null) { mDialog.getButtonCancel().setEnabled(false); } } }); } updateProgress(getPercentageOf(progress, ASSOCIATION_COMPLETE_PERCENT)); break; } B、授权组网成功
case DEVICE_ASSOCIATED: { /* Once association is completed we are approximately half way through the process. We still need to query lots of info from the device using MCP. The remaining 100 - ASSOCIATION_COMPLETE_PERCENT of the progress is used for that.*/ updateProgress(ASSOCIATION_COMPLETE_PERCENT); int deviceId = event.data.getInt(MeshConstants.EXTRA_DEVICE_ID); int uuidHash = event.data.getInt(MeshConstants.EXTRA_UUIDHASH_31); byte[] dhmKey = event.data.getByteArray(MeshConstants.EXTRA_RESET_KEY); mTempDevice = new UnknownDevice(); mTempDevice.setDeviceID(deviceId); mTempDevice.setDeviceHash(uuidHash); mTempDevice.setDmKey(dhmKey); mTempDevice.setPlaceID(Utils.getLatestPlaceIdUsed(this)); mTempDevice.setAssociated(true); AppearanceDevice appearanceDevice = mAppearances.get(uuidHash); /* Set to 2 as we always have to query model low and high. We may or may not need appearance and the number of models to query for groups is variable.*/ mNumPostAssociationSteps = 2; mPostAssociationStep = 0; if (appearanceDevice != null) { mTempDevice.setName(appearanceDevice.getShortName().trim() + " " + (deviceId - Constants.MIN_DEVICE_ID)); mTempDevice.setAppearance(appearanceDevice.getAppearanceType()); // Request model low from the device. mCurrentRequestState = DeviceInfo.MODEL_LOW; ConfigModel.getInfo(mTempDevice.getDeviceID(), DeviceInfo.MODEL_LOW); } else { // An extra step as we don't have the appearance yet. mNumPostAssociationSteps++; mTempDevice.setName(getString(R.string.unknown) + " " + (deviceId - Constants.MIN_DEVICE_ID)); // Request appearance from the device. mCurrentRequestState = DeviceInfo.APPEARANCE; ConfigModel.getInfo(mTempDevice.getDeviceID(), DeviceInfo.APPEARANCE); } mTempDevice = mDeviceManager.createOrUpdateDevice(mTempDevice, true); break; }
以上代码根据csrdemo2.1中copy,其实原理和1.3版本是一样的,那为什么看到代码发现比较复杂呢,
个人分析原型有二点,第一点:demo除了灯控模块还有集成了灯具、分组、情景、网关、云、sensor等模块,demo还增加了palce和area概念。
如有不足之处,希望各位大牛指正。对想了解这套系统的同行,希望对你们有帮助。