sensorium
Version:
makeblock mainboards protocol api
134 lines (125 loc) • 3.56 kB
JavaScript
/**
* @fileOverview 解析器负责数据解析,对外输出解析方法.
*/
import {
arrayFromArrayBuffer,
bytesToString,
calculateResponseValue
} from "./utils";
// 获取到的最大指令长度
const REC_BUF_MAX_LENGTH = 36;
const BUF_START_FLAG = [0xff, 0x55];
const BUF_END_FLAG = [0x0d, 0x0a];
function checkStart(flag1, flag2) {
return flag1 === BUF_START_FLAG[0] && flag2 === BUF_START_FLAG[1]
}
function checkEnd(flag1, flag2) {
return flag1 === BUF_END_FLAG[0] && flag2 === BUF_END_FLAG[1];
}
function findIndexOfStart(checkStart, data) {
for (let i = 0; i < data.length; i++) {
let data1 = data[i], data2 = data[i+1];
if (checkStart(data1, data2)) {
return i;
}
}
return -1;
}
export default {
cacheBuffer: [],
/**
* 解析从硬件传递过来的数据
* @param {Array} buffData buffer that from the response
* @return {Array|undefined} the parsed result
* data : 当前处理的数据
* this.cacheBuffer: 历史缓存数据, 记录数据和历史数据分开记录
*/
doParse: function(buffData) {
let result =[];
let data = arrayFromArrayBuffer(buffData);
let totalData = this.cacheBuffer.concat(data);
// 检测协议头 [ff, 55]
let index = findIndexOfStart(checkStart, totalData);
if(index > -1 ) {
totalData = totalData.slice(index);
// 更新缓存
this.cacheBuffer = totalData;
} else {
return undefined;
}
let tempBuffer = [];
for (let i = 2; i < totalData.length; i++) {
let data1 = totalData[i], data2 = totalData[i+1];
if (checkEnd(data1, data2)) {
result.push(tempBuffer);
// 下一帧数据
let nextFrame = totalData.slice(tempBuffer.length+4);
let nextFrameIndex = findIndexOfStart(checkStart, nextFrame);
// 清空容器
tempBuffer = [];
// 更新缓存
this.cacheBuffer = nextFrame;
if(nextFrameIndex === -1) {
break;
} else {
i += nextFrameIndex+3;
}
} else { // the data we really want
if (tempBuffer.length >= REC_BUF_MAX_LENGTH) {
console.warn("receive buffer overflow!");
}
tempBuffer.push(data1);
}
}
return result.length && result;
},
/**
* Get result from buffer data.
* @param {Array} buf array data.
* @return {Float} value of sensor's callback
* 回复数据数值解析, 从左到右第四位数据:
* 1: 单字符(1 byte)
* 2: float(4 byte)
* 3: short(2 byte),16个长度
* 4: 字符串
* 5: double(4 byte)
* 6: long(4 byte)
* @example
* ff 55 02 02 7c 1a 81 41 0d 0a
*/
getResult: function(buf) {
// 获取返回的数据类型
let dataType = buf[1];
let result = null;
switch (dataType) {
case "1":
case 1:
// 1byte
result = buf[2];
break;
case "3":
case 3:
// 2byte
result = calculateResponseValue([parseInt(buf[3]), parseInt(buf[2])]);
break;
case "4":
case 4:
// 字符串
var bytes = buf.splice(3, buf[2]);
result = bytesToString(bytes);
break;
case "2":
case "5":
case "6":
case 2:
case 5:
case 6:
// long型或者float型的4byte处理
result = calculateResponseValue([parseInt(buf[5]), parseInt(buf[4]), parseInt(buf[3]), parseInt(buf[2])]);
break;
default:
break;
}
return result;
}
}