我是靠谱客的博主 勤恳汉堡,最近开发中收集的这篇文章主要介绍cordova(android ios) ota给蓝牙设备升级1.用cordova(javascript)实现的具体代码如下1.1 打印截图2.遇到的问题一:iOS设备(iphone)上搜不到要进行ota的服务,如下:3.遇到问题二:Writing is not permitted,总是写数据失败,解决方法:ble.writeWithoutResponse4.ota的校验,readAck(),觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
官方指导
cordova蓝牙插件,总结
文章目录
- 1.用cordova(javascript)实现的具体代码如下
- 1.1 打印截图
- 2.遇到的问题一:iOS设备(iphone)上搜不到要进行ota的服务,如下:
- 2.1.猜想原因,android上和iOS上同一个服务展示出的uuid不同,安卓上是00002600-0000-1000-8000-00805F9B34FB,而iOS上是2600(亲测证明我的猜想是正确的)
- 3.遇到问题二:Writing is not permitted,总是写数据失败,解决方法:ble.writeWithoutResponse
- 4.ota的校验,readAck()
1.用cordova(javascript)实现的具体代码如下
//ota服务
var UUID_SERVICE_BLUEX_OTA
//ota控制特征
var UUID_CHARACTERISTIC_OTA_CTRL
//ota数据特征
var UUID_CHARACTERISTIC_OTA_DATA
if(navigator.platform == "iPhone"){
UUID_SERVICE_BLUEX_OTA = '2600'
UUID_CHARACTERISTIC_OTA_CTRL = '7000'
UUID_CHARACTERISTIC_OTA_DATA = '7001'
}else{
UUID_SERVICE_BLUEX_OTA = '00002600-0000-1000-8000-00805F9B34FB'
UUID_CHARACTERISTIC_OTA_CTRL = '00007000-0000-1000-8000-00805F9B34FB'
UUID_CHARACTERISTIC_OTA_DATA = '00007001-0000-1000-8000-00805F9B34FB'
}
var REQUEST_CTRL_OTA_START = 0 //刚开始发送文件数据之前先告诉设备,我要OTA,发文件了。
var RESPONSE_CTRL_OTA_START = 1 //设备接到手机端发来的信息,返回给手机我准备好了,发OTA文件来吧。
var REQUEST_CTRL_NEW_BLOCK = 2 //手机说:我要发一个新的数据块了。
var REQUEST_CTRL_DATA_FINISH = 3 //手机说:我把OTA文件都发完了。
function Segment() {}
Segment.prototype.index = 0
Segment.prototype.segBytes = [-1]
function Block() {}
Block.prototype.index = 0
Block.prototype.segments = [new Segment()]
Block.prototype.allBytesInBlock = [1,2]
var maxSegmentBytesLength = 19
var tasks = [] //blockarr
var currentBlockIndex = 0
var currentSegmentIndex = 0
var maxSegmentNumInBlock = 168
var firmware = []
function createTasks() {
function addFullBlock() {
for(var i = 0; i < blocksLength; i++) {
var block = new Block()
block.index = i
block.allBytesInBlock = firmware.slice(i*maxBlockBytesLength, (i+1)*maxBlockBytesLength )
parseBlock(block)
blocks.push(block)
}
}
var blocks = []
//一个block(区块)的最大字节长度
var maxBlockBytesLength = maxSegmentNumInBlock * maxSegmentBytesLength
var blocksLength = parseInt(firmware.length / maxBlockBytesLength)
if(firmware.length % maxBlockBytesLength == 0) {
addFullBlock()
} else {
addFullBlock()
var block = new Block()
block.index = blocksLength
block.allBytesInBlock = firmware.slice(blocksLength*maxBlockBytesLength, firmware.length)
parseBlock(block)
blocks.push(block)
}
tasks = blocks
}
function parseBlock(block) {
var segments = []
var index = parseInt(block.allBytesInBlock.length / maxSegmentBytesLength)
function addFullSegment() {
for(var i = 0; i < index; i++) {
var segment = new Segment()
segment.index = i
segment.segBytes = block.allBytesInBlock.slice(i*maxSegmentBytesLength, (i+1)*maxSegmentBytesLength)
segments.push(segment)
}
}
if(block.allBytesInBlock.length % maxSegmentBytesLength == 0) {
addFullSegment()
} else {
addFullSegment()
var segment = new Segment()
segment.index = index
segment.segBytes = block.allBytesInBlock.slice(index*maxSegmentBytesLength, block.allBytesInBlock.length)
segments.push(segment)
}
block.segments = segments
}
function prepareAndStartOta() {
console.log(currentMy.bleId)
console.log(UUID_SERVICE_BLUEX_OTA)
console.log(UUID_CHARACTERISTIC_OTA_CTRL)
ble.startNotification(currentMy.bleId, UUID_SERVICE_BLUEX_OTA, UUID_CHARACTERISTIC_OTA_CTRL, otaReceiveBlueData, function(data){
console.log("ota读取数据失败")
console.log(data)
})
window.resolveLocalFileSystemURL(cordova.file.applicationDirectory, function (dirEntry) {
console.log('file system open: ' + dirEntry.name);
console.log(dirEntry);
console.log(dirEntry.nativeURL);
dirEntry.getFile("www/test.bin",{create : false},function(fileEntry){
console.log(fileEntry)
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function() {
console.log("Successful file read: " + this.result);
console.log(this.result)
// firmware = this.result
firmware = new Uint8Array(this.result)
startOta()
};
reader.readAsArrayBuffer(file);
})
},function(error){
console.log(error)
})
}, function(){});
currentBlockIndex = -1
}
function startOta() {
var startBytes = [REQUEST_CTRL_OTA_START, maxSegmentBytesLength, maxSegmentBytesLength >> 8]
var crcHex = crc32(firmware)
var lengthHex = firmware.length.toString(16)
var arr1 = startBytes.concat(Str2Bytes(crcHex))
var arr2 = arr1.concat(Str2Bytes(lengthHex))
console.log(Bytes2Str(arr2))
dataType = 0
otaSendIntArr(arr2)
}
//十六进制字符串转字节数组(反过来)
function Str2Bytes(str) {
switch (str.length) {
case 3:
str = "00000" + str;
break;
case 4:
str = "0000" + str;
break;
case 5:
str = "000" + str;
break;
case 6:
str = "00" + str;
break;
case 7:
str = "0" + str;
break;
}
var pos = 0;
var len = str.length;
len /= 2;
var hexA = new Array();
pos = len * 2 - 2
for (var i = 0; i < len; i++) {
var s = str.substr(pos, 2);
var v = parseInt(s, 16);
hexA.push(v);
pos -= 2;
}
return hexA;
}
//字节数组转十六进制字符串
function Bytes2Str(arr) {
var str = "";
for (var i = 0; i < arr.length; i++) {
var tmp = arr[i].toString(16);
if (tmp.length == 1) {
tmp = "0" + tmp;
}
str += tmp;
}
return str;
}
function otaReceiveBlueData(buffer) {
var data = new Uint8Array(buffer);
var intArr = uint8ArrToInt(data)
console.log("ota收到数据")
console.log(data)
console.log(Bytes2Str(intArr))
if(data[0] == RESPONSE_CTRL_OTA_START && data[1] == 0) {
// maxSegmentNumInBlock = data[2]
createTasks()
console.log("设备说准备好了,开始升级")
console.log("一共"+tasks.length+"个block")
sendNewBlock()
} else if (data[0] == REQUEST_CTRL_NEW_BLOCK) {
// newBlock()
} else {
console.log("更新失败")
}
}
function sendNewBlock() {
if(currentBlockIndex + 1 == tasks.length) {
sendFinish()
return
}
currentBlockIndex++
var newBlockArr = [REQUEST_CTRL_NEW_BLOCK, currentBlockIndex, currentBlockIndex >> 8]
dataType = 1
otaSendIntArr(newBlockArr)
}
function uint8ArrToInt(uint8Arr) {
var arr = []
for (var i = 0; i < uint8Arr.length; i++) {
arr.push(uint8Arr[i])
}
return arr
}
function readDataAck() {
ble.read(currentMy.bleId, UUID_SERVICE_BLUEX_OTA, UUID_CHARACTERISTIC_OTA_DATA,function(data){
var intArr = uint8ArrToInt(new Uint8Array(data))
var segmentNum = block.segments.length
if(testDebug){
console.log(Bytes2Str(intArr))
console.log(segmentNum)
}
for(var i = 0; i < segmentNum; i++) {
var sent = intArr[parseInt(i/8)] & (1 << (i%8)) != 0
if(!sent){
updateFailedShow()
ble.disconnect(currentMy.bleId,function(){
console.log("断开连接成功");
},function(data){
console.log("断开连接失败"+data)
});
return
}
}
sendNewBlock()
},function(data){
updateFailedShow()
console.log("read数据失败")
console.log(data)
})
}
function sendFinish(){
var data = [REQUEST_CTRL_DATA_FINISH]
dataType = 0
console.log("finish")
updateSuccessful()
isUpdating = false
otaSendIntArr(data)
}
function segmentNextStep() {
var percent = currentSegmentIndex/(block.segments.length - 1)/tasks.length + currentBlockIndex /tasks.length
var num = (percent*100).toFixed(1)
$(".sofUpdateSpan").html(num+"%")
if(isUpdating == false){
//退出更新界面后会用到
console.log("进来isUpdating")
return
}
// console.log(num)
currentSegmentIndex++
transferSegment()
}
var block;
function newBlock() {
currentSegmentIndex = 0
block = tasks[currentBlockIndex]
if(testDebug){
console.log("第"+currentBlockIndex+"个block")
}
transferSegment()
}
function transferSegment() {
if(currentSegmentIndex > block.segments.length - 1) {
//校验
readDataAck()
return
}
var segBytes = uint8ArrToInt(block.segments[currentSegmentIndex].segBytes)
var data = [currentSegmentIndex].concat(segBytes)
otaSendIntArrData(data)
}
//现在发的是什么类型的数据 0:非block, 1:newBlock
var dataType = 0
function otaSendIntArr(intArr) {
var sendData = new Uint8Array(intArr);
if(testDebug){
console.log("发ota数据")
console.log(Bytes2Str(intArr))
}
ble.write(currentMy.bleId, UUID_SERVICE_BLUEX_OTA, UUID_CHARACTERISTIC_OTA_CTRL, sendData.buffer,function(data){
// console.log("ota数据发成功")
// console.log(data)
if(dataType == 1){
newBlock()
}
},function(data){
updateFailedShow()
console.log("ota数据发失败")
console.log(data)
})
}
function otaSendIntArrData(intArr) {
var sendData = new Uint8Array(intArr);
// console.log("发ota数据")
// console.log(Bytes2Str(intArr))
ble.writeWithoutResponse(currentMy.bleId, UUID_SERVICE_BLUEX_OTA, UUID_CHARACTERISTIC_OTA_DATA, sendData.buffer,function(data){
// console.log("ota数据发成功")
var timer = setTimeout(function(time){
segmentNextStep()
clearTimeout(timer);
},4);
},function(data){
updateFailedShow()
console.log("ota数据发失败")
console.log(data)
})
}
1.1 打印截图
2.遇到的问题一:iOS设备(iphone)上搜不到要进行ota的服务,如下:
android手机:下图中的unknown Service就是进行ota的service
iphone: 在iphone上却找不到和android上用来ota的相同服务
2.1.猜想原因,android上和iOS上同一个服务展示出的uuid不同,安卓上是00002600-0000-1000-8000-00805F9B34FB,而iOS上是2600(亲测证明我的猜想是正确的)
3.遇到问题二:Writing is not permitted,总是写数据失败,解决方法:ble.writeWithoutResponse
Writing is not permitted
4.ota的校验,readAck()
校验代码代表的意思是,读取自己数组的每个元素的值都是0xff(255)
kotlin代码:
val sent = acks[i / 8].and(1.shl(i % 8).toByte()).unsignedByteToInt() != 0
if(sent){
//校验成功
}
javascript代码:
var sent = intArr[parseInt(i/8)] & (1 << (i%8)) != 0
最后
以上就是勤恳汉堡为你收集整理的cordova(android ios) ota给蓝牙设备升级1.用cordova(javascript)实现的具体代码如下1.1 打印截图2.遇到的问题一:iOS设备(iphone)上搜不到要进行ota的服务,如下:3.遇到问题二:Writing is not permitted,总是写数据失败,解决方法:ble.writeWithoutResponse4.ota的校验,readAck()的全部内容,希望文章能够帮你解决cordova(android ios) ota给蓝牙设备升级1.用cordova(javascript)实现的具体代码如下1.1 打印截图2.遇到的问题一:iOS设备(iphone)上搜不到要进行ota的服务,如下:3.遇到问题二:Writing is not permitted,总是写数据失败,解决方法:ble.writeWithoutResponse4.ota的校验,readAck()所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复